added support for views and synonyms

git-svn-id: https://svn.code.sf.net/p/jailer/code/trunk@1547 3dd849cd-670e-4645-a7cd-dd197c8d0e81
This commit is contained in:
rwisser
2018-02-06 08:39:46 +00:00
parent 37512feb68
commit edfc80ace1
16 changed files with 815 additions and 73 deletions
@@ -60,6 +60,12 @@
<key>CatalogOptions</key>
<value>0</value>
</entry>
<!--
<entry>
<key>includeSynonyms</key>
<value>true</value>
</entry>
-->
</jdbcProperties>
<statisticRenovator>
<scriptFileName>script/oracle/gatherStatistics.sql</scriptFileName>
@@ -69,6 +69,11 @@ public class MetaDataCache {
*/
private Map<String, List<Object[]>> cache;
/**
* Meta data of chached row set.
*/
private MDCResultSetMetaData resultSetMetaData;
/**
* Reads primary keys.
*
@@ -177,8 +182,15 @@ public class MetaDataCache {
metaDataCache.cache = new HashMap<String, List<Object[]>>();
ResultSetMetaData rsMetaData = rs.getMetaData();
int numCol = rsMetaData.getColumnCount();
String[] names = new String[numCol];
int[] types = new int[numCol];
for (int i = 0; i < numCol; ++i) {
names[i] = rsMetaData.getColumnName(i + 1);
types[i] = rsMetaData.getColumnType(i + 1);
}
while (rs.next()) {
int numCol = rsMetaData.getColumnCount();
Object[] row = new Object[numCol];
for (int i = 1; i < numCol; ++i) {
if (i >= 22 && DBMS.MSSQL.equals(session.dbms)) {
@@ -192,6 +204,7 @@ public class MetaDataCache {
}
}
String table = (String) row[2];
List<Object[]> rowList = metaDataCache.cache.get(table);
if (rowList == null) {
rowList = new LinkedList<Object[]>();
@@ -199,7 +212,7 @@ public class MetaDataCache {
}
rowList.add(row);
}
metaDataCache.resultSetMetaData = new MDCResultSetMetaData(rsMetaData.getColumnCount(), names, types);
rs.close();
if (metaDataCache.cache.isEmpty()) {
@@ -222,7 +235,9 @@ public class MetaDataCache {
rowList = new ArrayList<Object[]>();
}
return new CachedResultSet(rowList);
CachedResultSet result = new CachedResultSet(rowList);
result.resultSetMetaData = resultSetMetaData;
return result;
}
/**
@@ -405,6 +420,11 @@ public class MetaDataCache {
this.rowList = rowList;
}
public CachedResultSet(List<Object[]> rowList, int numCol, String[] names, int[] types) {
this.rowList = rowList;
this.resultSetMetaData = new MDCResultSetMetaData(numCol, names, types);
}
public int getSize() {
return rowList.size();
}
@@ -817,7 +817,9 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
} else {
((JLabel) render).setFont(highlightedRows.contains(rowSorter.convertRowIndexToModel(row)) ? bold : nonbold);
String text = ((JLabel) render).getText();
if (text.length() > 50) {
if (text.indexOf('\n') >= 0) {
((JLabel) render).setToolTipText(UIUtil.toHTML(text, 400));
} else if (text.length() > 30) {
((JLabel) render).setToolTipText(text);
}
}
@@ -3518,13 +3520,15 @@ public abstract class BrowserContentPane extends javax.swing.JPanel {
}
}
if (singleRowDetailsView == null) {
width = Math.min(width, 400);
width = Math.min(width, maxColumnWidth);
}
column.setPreferredWidth(width);
}
}
protected int maxColumnWidth = 400;
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
@@ -116,6 +116,7 @@ import net.sf.jailer.ui.constraintcheck.ConstraintChecker;
import net.sf.jailer.ui.databrowser.BrowserContentPane.SqlStatementTable;
import net.sf.jailer.ui.databrowser.Desktop.LayoutMode;
import net.sf.jailer.ui.databrowser.Desktop.RowBrowser;
import net.sf.jailer.ui.databrowser.metadata.MDGeneric;
import net.sf.jailer.ui.databrowser.metadata.MDSchema;
import net.sf.jailer.ui.databrowser.metadata.MDTable;
import net.sf.jailer.ui.databrowser.metadata.MetaDataDetailsPanel;
@@ -2905,12 +2906,18 @@ public class DataBrowser extends javax.swing.JFrame {
UIUtil.showException(this, "Error", e);
}
}
@Override
protected void onTableSelect(MDTable mdTable) {
metaDataDetailsPanel
.showMetaDataDetails(mdTable, getMetaDataSource(session).toTable(mdTable), datamodel.get());
}
@Override
protected void onMDOtherSelect(MDGeneric mdOther) {
metaDataDetailsPanel
.showMetaDataDetails(mdOther, datamodel.get());
}
@Override
protected void onSchemaSelect(MDSchema mdSchema) {
@@ -0,0 +1,203 @@
/*
* Copyright 2007 - 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.jailer.ui.databrowser.metadata;
import java.lang.reflect.Method;
import java.sql.DatabaseMetaData;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.datamodel.DataModel;
import net.sf.jailer.modelbuilder.MetaDataCache.CachedResultSet;
/**
* Information about the database.
*
* @author Ralf Wisser
*/
public class MDDatabase extends MDGeneric {
private final DataModel dataModel;
private final ExecutionContext executionContext;
/**
* Constructor.
*
* @param name the object name
*/
public MDDatabase(String name, MetaDataSource metaDataSource, DataModel dataModel, ExecutionContext executionContext) {
super(name, metaDataSource);
this.dataModel = dataModel;
this.executionContext = executionContext;
}
/**
* Gets the render of the database object.
*
* @return render of the database object
*/
public JComponent createRender() throws Exception {
List<Object[]> rowList = new ArrayList<Object[]>();
DatabaseMetaData md = getMetaDataSource().getSession().getMetaData();
String[] names = new String[] {
"getURL",
"getUserName",
"isReadOnly",
"getDatabaseMajorVersion",
"getDatabaseMinorVersion",
"getDatabaseProductName",
"getIdentifierQuoteString",
"getDatabaseProductVersion",
"getDriverName",
"getDriverVersion",
"getDriverMajorVersion",
"getDriverMinorVersion",
"getCatalogSeparator",
"getCatalogTerm",
"getSchemaTerm",
"getProcedureTerm",
"getJDBCMajorVersion",
"getJDBCMinorVersion",
"getResultSetHoldability",
"supportsNamedParameters",
"supportsMultipleOpenResults",
"supportsGetGeneratedKeys",
"getSQLStateType",
"locatorsUpdateCopy",
"supportsStatementPooling",
"generatedKeyAlwaysReturned",
"getRowIdLifetime",
"supportsCatalogsInTableDefinitions",
"supportsSchemasInTableDefinitions",
"supportsMixedCaseQuotedIdentifiers",
"storesUpperCaseQuotedIdentifiers",
"storesLowerCaseQuotedIdentifiers",
"storesMixedCaseQuotedIdentifiers",
"supportsAlterTableWithAddColumn",
"supportsAlterTableWithDropColumn",
"supportsTableCorrelationNames",
"supportsDifferentTableCorrelationNames",
"supportsANSI92IntermediateSQL",
"supportsIntegrityEnhancementFacility",
"supportsSchemasInProcedureCalls",
"supportsSchemasInIndexDefinitions",
"supportsSchemasInPrivilegeDefinitions",
"supportsCatalogsInIndexDefinitions",
"supportsCatalogsInPrivilegeDefinitions",
"supportsSubqueriesInComparisons",
"supportsSubqueriesInQuantifieds",
"supportsOpenCursorsAcrossCommit",
"supportsOpenCursorsAcrossRollback",
"supportsOpenStatementsAcrossCommit",
"supportsOpenStatementsAcrossRollback",
"getDefaultTransactionIsolation",
"supportsDataManipulationTransactionsOnly",
"dataDefinitionCausesTransactionCommit",
"dataDefinitionIgnoredInTransactions",
"autoCommitFailureClosesAllResultSets",
"supportsStoredFunctionsUsingCallSyntax",
"supportsCatalogsInProcedureCalls",
"storesMixedCaseIdentifiers",
"storesUpperCaseIdentifiers",
"supportsSavepoints",
"supportsMultipleResultSets",
"allProceduresAreCallable",
"allTablesAreSelectable",
"nullsAreSortedHigh",
"nullsAreSortedLow",
"nullsAreSortedAtStart",
"nullsAreSortedAtEnd",
"usesLocalFiles",
"usesLocalFilePerTable",
"supportsMixedCaseIdentifiers",
"storesLowerCaseIdentifiers",
"getSearchStringEscape",
"getExtraNameCharacters",
"supportsColumnAliasing",
"nullPlusNonNullIsNull",
"supportsConvert",
"supportsExpressionsInOrderBy",
"supportsOrderByUnrelated",
"supportsGroupBy",
"supportsGroupByUnrelated",
"supportsGroupByBeyondSelect",
"supportsLikeEscapeClause",
"supportsMultipleTransactions",
"supportsNonNullableColumns",
"supportsMinimumSQLGrammar",
"supportsCoreSQLGrammar",
"supportsExtendedSQLGrammar",
"supportsANSI92EntryLevelSQL",
"supportsANSI92FullSQL",
"supportsOuterJoins",
"supportsFullOuterJoins",
"supportsLimitedOuterJoins",
"isCatalogAtStart",
"supportsPositionedDelete",
"supportsPositionedUpdate",
"supportsSelectForUpdate",
"supportsSubqueriesInExists",
"supportsSubqueriesInIns",
"supportsCorrelatedSubqueries",
"supportsUnion",
"supportsUnionAll",
"getMaxBinaryLiteralLength",
"getMaxCharLiteralLength",
"getMaxColumnNameLength",
"getMaxColumnsInGroupBy",
"getMaxColumnsInIndex",
"getMaxColumnsInOrderBy",
"getMaxColumnsInSelect",
"getMaxColumnsInTable",
"getMaxConnections",
"getMaxCursorNameLength",
"getMaxIndexLength",
"getMaxSchemaNameLength",
"getMaxProcedureNameLength",
"getMaxCatalogNameLength",
"getMaxRowSize",
"doesMaxRowSizeIncludeBlobs",
"getMaxStatementLength",
"getMaxStatements",
"getMaxTableNameLength",
"getMaxTablesInSelect",
"getMaxUserNameLength",
"supportsTransactions",
"supportsBatchUpdates",
"supportsSchemasInDataManipulation",
"supportsCatalogsInDataManipulation",
"supportsStoredProcedures"
};
for (String name: names) {
try {
Method m = md.getClass().getMethod(name);
rowList.add(new Object[] { name.startsWith("get")? name.substring(3) : name, m.invoke(md) });
} catch (Throwable t) {
// ignore
}
}
CachedResultSet rs = new CachedResultSet(rowList, 2, new String[] { "Property", "Value" }, new int[] { Types.VARCHAR, Types.VARCHAR });
return new ResultSetRenderer(rs, getName(), dataModel, getMetaDataSource().getSession(), executionContext);
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2007 - 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.jailer.ui.databrowser.metadata;
import javax.swing.JComponent;
import javax.swing.JLabel;
/**
* Information about a database object other than schemas or tables.
*
* @author Ralf Wisser
*/
public abstract class MDGeneric extends MDObject {
private JComponent render;
/**
* Constructor.
*
* @param name the object name
*/
public MDGeneric(String name, MetaDataSource metaDataSource) {
super(name, metaDataSource);
}
/**
* Gets the render of the database object.
*
* @return render of the database object
*/
public final JComponent getRender() {
if (render == null) {
try {
render = createRender();
} catch (Throwable t) {
render = new JLabel("Error: " + t.getMessage());
}
}
return render;
}
/**
* creates the render of the database object.
*
* @return render of the database object
*/
public abstract JComponent createRender() throws Exception;
}
@@ -111,7 +111,7 @@ public class MDSchema extends MDObject {
Map<String, Runnable> loadJobs = new TreeMap<String, Runnable>();
while (rs.next()) {
String tableName = metaDataSource.getQuoting().quote(rs.getString(3));
final MDTable table = new MDTable(tableName, this, "VIEW".equalsIgnoreCase(rs.getString(4)), "SYNONYM".equalsIgnoreCase(rs.getString(4)));
final MDTable table = new MDTable(tableName, this, "VIEW".equalsIgnoreCase(rs.getString(4)), "SYNONYM".equalsIgnoreCase(rs.getString(4)) || "ALIAS".equalsIgnoreCase(rs.getString(4)));
tables.add(table);
if (loadTableColumns) {
loadJobs.put(tableName, new Runnable() {
@@ -151,7 +151,8 @@ public class MDTable extends MDObject {
try {
MetaDataSource metaDataSource = getMetaDataSource();
synchronized (metaDataSource.getSession().getMetaData()) {
ResultSet resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(getSchema().getMetaDataSource().getSession(), getSchema().getMetaDataSource().getSession().getMetaData(), Quoting.staticUnquote(getSchema().getName()), Quoting.staticUnquote(getName()), "%", false);
ResultSet resultSet = JDBCMetaDataBasedModelElementFinder.getColumns(getSchema().getMetaDataSource().getSession(), getSchema().getMetaDataSource().getSession().getMetaData(), Quoting.staticUnquote(getSchema().getName()), Quoting.staticUnquote(getName()), "%",
true);
while (resultSet.next()) {
String colName = metaDataSource.getQuoting().quote(resultSet.getString(4));
columns.add(colName);
@@ -36,7 +36,7 @@ public enum MetaDataDetails {
COLUMNS("Columns", 0) {
public ResultSet readMetaDataDetails(Session session, MDTable mdTable) throws SQLException {
return JDBCMetaDataBasedModelElementFinder.getColumns(session, session.getMetaData(), Quoting.staticUnquote(mdTable.getSchema().getName()), Quoting.staticUnquote(mdTable.getName()), "%", false);
return JDBCMetaDataBasedModelElementFinder.getColumns(session, session.getMetaData(), Quoting.staticUnquote(mdTable.getSchema().getName()), Quoting.staticUnquote(mdTable.getName()), "%", true);
}
public void adjustRowsTable(JTable rowsTable) {
TableColumnModel columnModel = rowsTable.getColumnModel();
@@ -14,9 +14,14 @@
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="table"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
@@ -42,5 +47,14 @@
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="otherPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="other"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
</Container>
</SubComponents>
</Form>
@@ -16,6 +16,7 @@
package net.sf.jailer.ui.databrowser.metadata;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
@@ -99,6 +100,7 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
tabbedPane.addTab("DDL", ddlPanel);
}
}
((CardLayout) getLayout()).show(this, "table");
}
static {
@@ -130,8 +132,16 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
tableDetailsViews.clear();
}
public void showMetaDataDetails(MDGeneric mdOther, DataModel dataModel2) {
setVisible(true);
((CardLayout) getLayout()).show(this, "other");
otherPanel.removeAll();
otherPanel.add(mdOther.getRender());
}
public void showMetaDataDetails(final MDTable mdTable, Table table, DataModel dataModel) {
setVisible(true);
((CardLayout) getLayout()).show(this, "table");
tableDetailsPanel.removeAll();
if (table != null) {
JComponent view = tableDetailsViews.get(table);
@@ -419,8 +429,9 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
jPanel1 = new javax.swing.JPanel();
tabbedPane = new javax.swing.JTabbedPane();
tableDetailsPanel = new javax.swing.JPanel();
otherPanel = new javax.swing.JPanel();
setLayout(new javax.swing.BoxLayout(this, javax.swing.BoxLayout.LINE_AXIS));
setLayout(new java.awt.CardLayout());
jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.LINE_AXIS));
@@ -431,10 +442,14 @@ public abstract class MetaDataDetailsPanel extends javax.swing.JPanel {
jPanel1.add(tabbedPane);
add(jPanel1);
add(jPanel1, "table");
otherPanel.setLayout(new javax.swing.BoxLayout(otherPanel, javax.swing.BoxLayout.LINE_AXIS));
add(otherPanel, "other");
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel otherPanel;
private javax.swing.JTabbedPane tabbedPane;
private javax.swing.JPanel tableDetailsPanel;
// End of variables declaration//GEN-END:variables
@@ -40,6 +40,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -100,7 +101,12 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
private final MetaDataDetailsPanel metaDataDetailsPanel;
private final Frame parent;
private final JButton searchButton;
private final ExecutionContext executionContext;
private final Object CATEGORY_VIEWS = new String("Views");
private final Object CATEGORY_TABLES = new String("Tables");
private final Object CATEGORY_SYNONYMS = new String("Synonyms");
private abstract class ExpandingMutableTreeNode extends DefaultMutableTreeNode {
public ExpandingMutableTreeNode() {
@@ -123,6 +129,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
this.dataModel = dataModel;
this.metaDataDetailsPanel = metaDataDetailsPanel;
this.parent = parent;
this.executionContext = executionContext;
initComponents();
hideOutline();
@@ -391,8 +398,6 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
});
final ImageIcon finalScaledWarnIcon = getScaledIcon(this, warnIcon);
final ImageIcon finalScaledViewIcon = getScaledIcon(this, viewIcon);
final ImageIcon finalScaledSynonymIcon = getScaledIcon(this, synonymIcon);
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer() {
Map<MDTable, Boolean> dirtyTables = new HashMap<MDTable, Boolean>();
@@ -404,8 +409,24 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
boolean isView = false;
boolean isSynonym = false;
Boolean isDirty = false;
ImageIcon image = null;
if (value instanceof DefaultMutableTreeNode) {
Object uo = ((DefaultMutableTreeNode) value).getUserObject();
if (uo == CATEGORY_VIEWS) {
image = viewsIcon;
}
if (uo == CATEGORY_SYNONYMS) {
image = synonymsIcon;
}
if (uo == CATEGORY_TABLES) {
image = tablesIcon;
}
if (uo instanceof MDDatabase) {
image = databaseIcon;
}
if (uo instanceof MDSchema) {
image = schemaIcon;
}
if (uo instanceof MDTable) {
Table table = MetaDataPanel.this.metaDataSource.toTable((MDTable) uo);
if (table == null) {
@@ -424,9 +445,25 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
}
isView = ((MDTable) uo).isView();
isSynonym = ((MDTable) uo).isSynonym();
if (isView) {
image = viewIcon;
} else if (isSynonym) {
image = synonymIcon;
} else {
image = tableIcon;
}
}
}
Component comp = super.getTreeCellRendererComponent(tree, value + (unknownTable? "" : (isDirty? " !" : " ")), sel, expanded, leaf, row, hasFocus);
String tooltip = null;
if (comp instanceof JLabel) {
String text = ((JLabel) comp).getText();
int maxLength = 40;
if (text != null && text.length() > maxLength) {
tooltip = text;
((JLabel) comp).setText(text.substring(0, maxLength) + "...");
}
}
Font font = comp.getFont();
if (font != null) {
Font bold = new Font(font.getName(), unknownTable || isDirty? (font.getStyle() | Font.ITALIC) : (font.getStyle() & ~Font.ITALIC), font.getSize());
@@ -435,14 +472,14 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
if (isJailerTable) {
comp.setEnabled(false);
}
if (isView || isSynonym) {
if (image != null) {
JPanel panel = new JPanel(new FlowLayout(0, 0, 0));
panel.add(comp);
JLabel label = new JLabel(isView? finalScaledViewIcon : finalScaledSynonymIcon);
JLabel label = new JLabel(image);
label.setText(" ");
label.setOpaque(false);
panel.add(label);
panel.setOpaque(false);
panel.add(comp);
comp = panel;
}
JPanel panel = new JPanel(new FlowLayout(0, 0, 0));
@@ -454,6 +491,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
label.setOpaque(false);
panel.add(label);
panel.setOpaque(false);
panel.setToolTipText(tooltip);
comp = panel;
return comp;
}
@@ -481,19 +519,21 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
if (table != null) {
updateDataModelView(table);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (metaDataTree.getSelectionPath() != null && metaDataTree.getSelectionPath().getLastPathComponent() == last) {
if (uo instanceof MDSchema) {
onSchemaSelect((MDSchema) uo);
} else if (uo instanceof MDTable) {
onTableSelect((MDTable) uo);
}
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (metaDataTree.getSelectionPath() != null && metaDataTree.getSelectionPath().getLastPathComponent() == last) {
if (uo instanceof MDSchema) {
onSchemaSelect((MDSchema) uo);
} else if (uo instanceof MDTable) {
onTableSelect((MDTable) uo);
} else if (uo instanceof MDGeneric) {
onMDOtherSelect((MDGeneric) uo);
}
}
});
}
}
});
}
}
}
@@ -621,19 +661,27 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
private void scrollToNode(TreePath path) {
Rectangle bounds = metaDataTree.getPathBounds(path);
metaDataTree.scrollRectToVisible(new Rectangle(bounds.x, bounds.y, 1, bounds.height));
if (bounds != null) {
int b = 18;
bounds = new Rectangle(bounds.x, Math.max(bounds.y - b, 0), bounds.width, bounds.height + 2 * b);
metaDataTree.scrollRectToVisible(new Rectangle(bounds.x, bounds.y, 1, bounds.height));
}
}
private TreePath find(Object root, MDTable mdTable) {
if (root instanceof DefaultMutableTreeNode) {
Object userObject = ((DefaultMutableTreeNode) root).getUserObject();
if (userObject instanceof MDSchema) {
if (mdTable.getSchema().equals(userObject)) {
if (((DefaultMutableTreeNode) root).getChildCount() > 0) {
TreeNode firstChild = ((DefaultMutableTreeNode) root).getFirstChild();
if (firstChild instanceof ExpandingMutableTreeNode) {
((ExpandingMutableTreeNode) firstChild).expandImmediatelly();
int cc = ((DefaultMutableTreeNode) root).getChildCount();
for (int i = 0; i < cc; ++i) {
TreeNode catNode = ((DefaultMutableTreeNode) root).getChildAt(i);
Object catUO = ((DefaultMutableTreeNode) catNode).getUserObject();
if (catNode.getChildCount() > 0 && (CATEGORY_TABLES == catUO || CATEGORY_VIEWS == catUO || CATEGORY_SYNONYMS == catUO)) {
TreeNode firstChild = catNode.getChildAt(0);
if (firstChild instanceof ExpandingMutableTreeNode) {
((ExpandingMutableTreeNode) firstChild).expandImmediatelly();
}
}
}
}
@@ -652,53 +700,99 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
}
return null;
}
private DefaultMutableTreeNode root;
private Map<MDSchema, DefaultMutableTreeNode> treeNodePerSchema = new HashMap<MDSchema, DefaultMutableTreeNode>();
private void updateTreeModel(MetaDataSource metaDataSource) {
root = new DefaultMutableTreeNode(metaDataSource.dataSourceName);
root = new DefaultMutableTreeNode(new MDDatabase(metaDataSource.dataSourceName, metaDataSource, dataModel, executionContext));
for (final MDSchema schema: metaDataSource.getSchemas()) {
final DefaultMutableTreeNode schemaChild = new DefaultMutableTreeNode(schema);
root.add(schemaChild);
treeNodePerSchema.put(schema, schemaChild);
MutableTreeNode expandSchema = new ExpandingMutableTreeNode() {
private boolean expanded = false;
@Override
protected void expandImmediatelly() {
if (!expanded) {
for (MDTable table: schema.getTables()) {
DefaultMutableTreeNode tableChild = new DefaultMutableTreeNode(table);
schemaChild.add(tableChild);
}
schemaChild.remove(this);
TreeModel model = metaDataTree.getModel();
((DefaultTreeModel) model).nodeStructureChanged(schemaChild);
}
expanded = true;
}
@Override
protected void expand() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
expandImmediatelly();
} finally {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
});
}
};
schemaChild.add(expandSchema);
Iterable<Object> leafs = new Iterable<Object>() {
@Override
public Iterator<Object> iterator() {
List<Object> leafs = new ArrayList<Object>();
for (MDTable table: schema.getTables()) {
if (table.isView()) {
leafs.add(table);
}
}
return leafs.iterator();
}
};
createCategoryNode(schemaChild, leafs, CATEGORY_VIEWS);
leafs = new Iterable<Object>() {
@Override
public Iterator<Object> iterator() {
List<Object> leafs = new ArrayList<Object>();
for (MDTable table: schema.getTables()) {
if (table.isSynonym()) {
leafs.add(table);
}
}
return leafs.iterator();
}
};
createCategoryNode(schemaChild, leafs, CATEGORY_SYNONYMS);
leafs = new Iterable<Object>() {
@Override
public Iterator<Object> iterator() {
List<Object> leafs = new ArrayList<Object>();
for (MDTable table: schema.getTables()) {
if (!table.isView() && !table.isSynonym()) {
leafs.add(table);
}
}
return leafs.iterator();
}
};
DefaultMutableTreeNode schemaTablesChild = createCategoryNode(schemaChild, leafs, CATEGORY_TABLES);
treeNodePerSchema.put(schema, schemaTablesChild);
}
DefaultTreeModel treeModel = new DefaultTreeModel(root);
metaDataTree.setModel(treeModel);
selectSchema(metaDataSource.getDefaultSchema());
}
public DefaultMutableTreeNode createCategoryNode(final DefaultMutableTreeNode schemaChild, final Iterable<Object> leafs,
Object category) {
final DefaultMutableTreeNode schemaViewsChild = new DefaultMutableTreeNode(category);
schemaChild.add(schemaViewsChild);
root.add(schemaChild);
MutableTreeNode expandSchema = new ExpandingMutableTreeNode() {
private boolean expanded = false;
@Override
protected void expandImmediatelly() {
if (!expanded) {
for (Object leaf: leafs) {
DefaultMutableTreeNode tableChild = new DefaultMutableTreeNode(leaf);
schemaViewsChild.add(tableChild);
}
schemaViewsChild.remove(this);
TreeModel model = metaDataTree.getModel();
((DefaultTreeModel) model).nodeStructureChanged(schemaViewsChild);
}
expanded = true;
}
@Override
protected void expand() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
expandImmediatelly();
} finally {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
});
}
};
schemaViewsChild.add(expandSchema);
return schemaViewsChild;
}
public void selectSchema(MDSchema mdSchema) {
selectSchema(mdSchema, true);
}
@@ -707,7 +801,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
if (mdSchema != null) {
DefaultMutableTreeNode node = treeNodePerSchema.get(mdSchema);
if (node != null) {
TreePath path = new TreePath(new Object[] { root, node });
TreePath path = new TreePath(node.getPath());
metaDataTree.expandPath(path);
metaDataTree.getSelectionModel().setSelectionPath(path);
if (scrollToNode) {
@@ -1042,6 +1136,7 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
protected abstract void analyseSchema(String schemaName);
protected abstract void onTableSelect(MDTable mdTable);
protected abstract void onSchemaSelect(MDSchema mdSchema);
protected abstract void onMDOtherSelect(MDGeneric mdOther);
protected abstract void openNewTableBrowser();
protected abstract void updateDataModelView(Table table);
protected abstract void setCaretPosition(int position);
@@ -1068,7 +1163,13 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
static ImageIcon warnIcon;
static ImageIcon viewIcon;
static ImageIcon viewsIcon;
static ImageIcon tableIcon;
static ImageIcon tablesIcon;
static ImageIcon synonymIcon;
static ImageIcon synonymsIcon;
static ImageIcon databaseIcon;
static ImageIcon schemaIcon;
static ImageIcon getScaledIcon(JComponent component, ImageIcon icon) {
if (icon != null) {
@@ -1095,10 +1196,16 @@ public abstract class MetaDataPanel extends javax.swing.JPanel {
try {
warnIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/wanr.png"));
viewIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/view.png"));
synonymIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/right.png"));
synonymIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/synonym.png"));
synonymsIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/synonyms.png"));
viewsIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/views.png"));
tablesIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/tables.png"));
tableIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/table.png"));
databaseIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/database.png"));
schemaIcon = new ImageIcon(MetaDataPanel.class.getResource(dir + "/schema.png"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -119,7 +119,11 @@ public class MetaDataSource {
}
ResultSet readTables(String schemaPattern) throws SQLException {
return JDBCMetaDataBasedModelElementFinder.getTables(session, session.getMetaData(), Quoting.staticUnquote(schemaPattern), "%", new String[] { "TABLE", "VIEW" /* , "SYNONYM" */ });
try {
return JDBCMetaDataBasedModelElementFinder.getTables(session, session.getMetaData(), Quoting.staticUnquote(schemaPattern), "%", new String[] { "TABLE", "VIEW", "SYNONYM", "ALIAS" });
} catch (Exception e) {
return JDBCMetaDataBasedModelElementFinder.getTables(session, session.getMetaData(), Quoting.staticUnquote(schemaPattern), "%", new String[] { "TABLE", "VIEW" });
}
}
/**
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="titelLabel">
<Properties>
<Property name="text" type="java.lang.String" value="jLabel1"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="renderPanel">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
</Container>
<Component class="javax.swing.JSeparator" name="jSeparator1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="2" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Form>
@@ -0,0 +1,253 @@
/*
* Copyright 2007 - 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.jailer.ui.databrowser.metadata;
import java.awt.Frame;
import java.awt.Window;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.PriorityBlockingQueue;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.database.Session;
import net.sf.jailer.datamodel.Association;
import net.sf.jailer.datamodel.DataModel;
import net.sf.jailer.datamodel.Table;
import net.sf.jailer.ui.DbConnectionDialog;
import net.sf.jailer.ui.QueryBuilderDialog;
import net.sf.jailer.ui.QueryBuilderDialog.Relationship;
import net.sf.jailer.ui.databrowser.BrowserContentPane;
import net.sf.jailer.ui.databrowser.BrowserContentPane.LoadJob;
import net.sf.jailer.ui.databrowser.Desktop;
import net.sf.jailer.ui.databrowser.Desktop.RowBrowser;
import net.sf.jailer.ui.databrowser.Row;
import net.sf.jailer.ui.databrowser.sqlconsole.SQLConsole;
import net.sf.jailer.util.Pair;
/**
* Renders content of {@link ResultSet}.
*
* @author Ralf Wisser
*/
public class ResultSetRenderer extends javax.swing.JPanel {
/**
* Creates new form ResultSetRenderer
* @param executionContext
*/
public ResultSetRenderer(ResultSet resultSet, String titel, DataModel datamodel, Session session, ExecutionContext executionContext) {
initComponents();
titelLabel.setText(titel);
final BrowserContentPane rb = new ResultContentPane(datamodel, null, "", session, null, null,
null, null, new HashSet<Pair<BrowserContentPane, Row>>(), new HashSet<Pair<BrowserContentPane, String>>(), Integer.MAX_VALUE, false, false, executionContext);
rb.setTableFilterEnabled(false);
LoadJob loadJob = rb.newLoadJob(resultSet, Integer.MAX_VALUE);
loadJob.run();
JComponent rTabContainer = rb.getRowsTableContainer();
rb.sortColumnsCheckBox.setVisible(false);
renderPanel.add(rTabContainer);
rb.resetRowsTableContainer();
renderPanel.repaint();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
titelLabel = new javax.swing.JLabel();
renderPanel = new javax.swing.JPanel();
jSeparator1 = new javax.swing.JSeparator();
setLayout(new java.awt.GridBagLayout());
titelLabel.setText("jLabel1");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
add(titelLabel, gridBagConstraints);
renderPanel.setLayout(new javax.swing.BoxLayout(renderPanel, javax.swing.BoxLayout.LINE_AXIS));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
add(renderPanel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
add(jSeparator1, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JSeparator jSeparator1;
private javax.swing.JPanel renderPanel;
private javax.swing.JLabel titelLabel;
// End of variables declaration//GEN-END:variables
class ResultContentPane extends BrowserContentPane {
public ResultContentPane(DataModel dataModel, Table table, String condition, Session session, Row parentRow,
List<Row> parentRows, Association association, Frame parentFrame,
Set<Pair<BrowserContentPane, Row>> currentClosure,
Set<Pair<BrowserContentPane, String>> currentClosureRowIDs, Integer limit, Boolean selectDistinct,
boolean reload, ExecutionContext executionContext) {
super(dataModel, table, condition, session, parentRow, parentRows, association, parentFrame, currentClosure,
currentClosureRowIDs, limit, selectDistinct, reload, executionContext);
noSingleRowDetailsView = true;
maxColumnWidth = 180;
rowsTableScrollPane.setWheelScrollingEnabled(true);
rowsCount.setVisible(false);
}
@Override
protected void unhide() {
}
@Override
protected void showInNewWindow() {
}
@Override
protected void reloadDataModel() throws Exception {
}
@Override
protected void openSchemaMappingDialog() {
}
@Override
protected void openSchemaAnalyzer() {
}
@Override
protected void onRedraw() {
ResultSetRenderer.this.repaint();
}
@Override
protected void onHide() {
}
@Override
protected void onContentChange(List<Row> rows, boolean reloadChildren) {
}
@Override
protected void navigateTo(Association association, int rowIndex, Row row) {
}
@Override
protected List<RowBrowser> getTableBrowser() {
return null;
}
@Override
protected PriorityBlockingQueue<RunnableWithPriority> getRunnableQueue() {
return Desktop.runnableQueue;
}
@Override
protected QueryBuilderDialog getQueryBuilderDialog() {
return null;
}
@Override
protected RowBrowser getParentBrowser() {
return null;
}
@Override
protected JFrame getOwner() {
Window owner = SwingUtilities.getWindowAncestor(ResultSetRenderer.this);
if (owner instanceof JFrame) {
return (JFrame) owner;
}
return null;
}
@Override
protected double getLayoutFactor() {
return 0;
}
@Override
protected DbConnectionDialog getDbConnectionDialog() {
return null;
}
@Override
protected List<RowBrowser> getChildBrowsers() {
return new ArrayList<RowBrowser>();
}
@Override
protected void findClosure(Row row, Set<Pair<BrowserContentPane, Row>> closure, boolean forward) {
Pair<BrowserContentPane, Row> thisRow = new Pair<BrowserContentPane, Row>(this, row);
if (!closure.contains(thisRow)) {
closure.add(thisRow);
}
}
@Override
protected void findClosure(Row row) {
Set<Pair<BrowserContentPane, Row>> rows = new HashSet<Pair<BrowserContentPane, Row>>();
findClosure(row, rows, false);
currentClosure.addAll(rows);
rows = new HashSet<Pair<BrowserContentPane, Row>>();
findClosure(row, rows, true);
currentClosure.addAll(rows);
}
@Override
protected Relationship createQBRelations(boolean withParents) {
return null;
}
@Override
protected List<Relationship> createQBChildrenRelations(RowBrowser tabu, boolean all) {
return null;
}
@Override
protected void collectPositions(Map<String, Map<String, double[]>> positions) {
}
@Override
protected void close() {
}
@Override
protected void beforeReload() {
}
@Override
protected void appendLayout() {
}
@Override
protected void adjustClosure(BrowserContentPane tabu) {
}
@Override
protected void addRowToRowLink(Row pRow, Row exRow) {
}
@Override
protected boolean renderRowAsPK(Row theRow) {
return false;
}
@Override
protected MetaDataSource getMetaDataSource() {
return null;
}
@Override
protected SQLConsole getSqlConsole(boolean switchToConsole) {
return null;
}
};
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 307 B