This is an automated email from the ASF dual-hosted git repository.
mattcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 0d1c875eaf Polishing the database exploration dialog #5376 (#8353)
0d1c875eaf is described below
commit 0d1c875eaffbf89f2c680c410335c38d4df6763a
Author: Nicolas Adment <[email protected]>
AuthorDate: Tue Sep 15 19:03:57 2026 +0200
Polishing the database exploration dialog #5376 (#8353)
Co-authored-by: mattcasters <[email protected]>
---
.../hop/core/database/DatabaseMetaInformation.java | 35 +-
.../hop/core/database/DatabasePluginType.java | 2 +-
.../database/DatabaseTreeNode.java | 32 +-
.../hop/ui/core/database/DatabaseTreeUtil.java | 100 ++
.../database/dialog/DatabaseExplorerDialog.java | 1516 +++++++++-----------
.../dialog/GetDatabaseInfoProgressDialog.java | 4 +-
.../hop/ui/core/database/dialog/SqlEditor.java | 96 +-
.../org/apache/hop/ui/core/gui/GuiResource.java | 4 +
.../perspective/database/DatabaseTableInfoTab.java | 1 +
.../perspective/database/DatabaseWorkbench.java | 59 +-
.../dialog/messages/messages_de_DE.properties | 14 +-
.../dialog/messages/messages_en_US.properties | 23 +-
.../dialog/messages/messages_es_AR.properties | 14 +-
.../dialog/messages/messages_es_ES.properties | 14 +-
.../dialog/messages/messages_fr_FR.properties | 14 +-
.../dialog/messages/messages_it_IT.properties | 14 +-
.../dialog/messages/messages_ja_JP.properties | 2 +-
.../dialog/messages/messages_ko_KR.properties | 4 +-
.../dialog/messages/messages_pt_BR.properties | 8 +-
.../dialog/messages/messages_zh_CN.properties | 2 +-
ui/src/main/resources/ui/images/layout.svg | 3 +
ui/src/main/resources/ui/images/regex-disabled.svg | 3 +
ui/src/main/resources/ui/images/regex.svg | 23 +-
ui/src/main/resources/ui/images/run-all.svg | 8 +-
.../perspective/database/DatabaseTreeNodeTest.java | 22 +-
25 files changed, 941 insertions(+), 1076 deletions(-)
diff --git
a/core/src/main/java/org/apache/hop/core/database/DatabaseMetaInformation.java
b/core/src/main/java/org/apache/hop/core/database/DatabaseMetaInformation.java
index 2845372ee6..9c758caec1 100644
---
a/core/src/main/java/org/apache/hop/core/database/DatabaseMetaInformation.java
+++
b/core/src/main/java/org/apache/hop/core/database/DatabaseMetaInformation.java
@@ -23,6 +23,7 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
@@ -70,9 +71,8 @@ public class DatabaseMetaInformation {
}
monitor.beginTask(BaseMessages.getString(PKG,
"DatabaseMeta.Info.GettingInfoFromDb"), 8);
- Database db = new Database(parentLoggingObject, variables, databaseMeta);
- try {
+ try (Database db = new Database(parentLoggingObject, variables,
databaseMeta)) {
monitor.subTask(BaseMessages.getString(PKG,
"DatabaseMeta.Info.ConnectingDb"));
db.connect();
monitor.worked(1);
@@ -93,18 +93,17 @@ public class DatabaseMetaInformation {
monitor.subTask(BaseMessages.getString(PKG,
"DatabaseMeta.Info.GettingInfo"));
Map<String, String> connectionExtraOptions =
databaseMeta.getExtraOptions();
if (databaseMeta.supportsCatalogs() &&
dbmd.supportsCatalogsInTableDefinitions()) {
- ArrayList<Catalog> catalogList = new ArrayList<>();
+ List<Catalog> catalogs = new ArrayList<>();
String catalogFilterKey = databaseMeta.getPluginId() + "." +
FILTER_CATALOG_LIST;
if ((connectionExtraOptions != null)
&& connectionExtraOptions.containsKey(catalogFilterKey)) {
- String catsFilterCommaList =
connectionExtraOptions.get(catalogFilterKey);
- String[] catsFilterArray = catsFilterCommaList.split(",");
- for (String s : catsFilterArray) {
- catalogList.add(new Catalog(s.trim()));
+ String catalogsFilterCommaList =
connectionExtraOptions.get(catalogFilterKey);
+ for (String name : catalogsFilterCommaList.split(",")) {
+ catalogs.add(new Catalog(name.trim()));
}
}
- if (catalogList.isEmpty()) {
+ if (catalogs.isEmpty()) {
ResultSet catalogResultSet = dbmd.getCatalogs();
// Grab all the catalog names and put them in an array list
@@ -113,7 +112,7 @@ public class DatabaseMetaInformation {
//
while (catalogResultSet != null && catalogResultSet.next()) {
String catalogName = catalogResultSet.getString(1);
- catalogList.add(new Catalog(catalogName));
+ catalogs.add(new Catalog(catalogName));
}
// Close the catalogs resultset immediately
@@ -123,7 +122,7 @@ public class DatabaseMetaInformation {
// Now loop over the catalogs...
//
- for (Catalog catalog : catalogList) {
+ for (Catalog catalog : catalogs) {
ArrayList<String> catalogTables = new ArrayList<>();
try {
@@ -149,11 +148,11 @@ public class DatabaseMetaInformation {
// Save the list of tables in the catalog (can be empty)
//
- catalog.setItems(catalogTables.toArray(new
String[catalogTables.size()]));
+ catalog.setItems(catalogTables.toArray(new String[0]));
}
// Save for later...
- setCatalogs(catalogList.toArray(new Catalog[catalogList.size()]));
+ setCatalogs(catalogs.toArray(new Catalog[0]));
}
monitor.worked(1);
if (monitor.isCanceled()) {
@@ -164,7 +163,7 @@ public class DatabaseMetaInformation {
//
monitor.subTask(BaseMessages.getString(PKG,
"DatabaseMeta.Info.GettingSchemaInfo"));
if (databaseMeta.supportsSchemas() &&
dbmd.supportsSchemasInTableDefinitions()) {
- ArrayList<Schema> schemaList = new ArrayList<>();
+ List<Schema> schemaList = new ArrayList<>();
try {
String schemaFilterKey = databaseMeta.getPluginId() + "." +
FILTER_SCHEMA_LIST;
if ((connectionExtraOptions != null)
@@ -204,7 +203,7 @@ public class DatabaseMetaInformation {
}
}
for (Schema schema : schemaList) {
- ArrayList<String> schemaTables = new ArrayList<>();
+ List<String> schemaTables = new ArrayList<>();
try {
ResultSet schemaTablesResultSet = null;
@@ -237,7 +236,7 @@ public class DatabaseMetaInformation {
// Just ignore it!
}
- schema.setItems(schemaTables.toArray(new
String[schemaTables.size()]));
+ schema.setItems(schemaTables.toArray(new String[0]));
if (monitor.isCanceled()) {
return;
@@ -249,8 +248,7 @@ public class DatabaseMetaInformation {
}
// Sort the schemas by names
- Collections.sort(
- schemaList,
+ schemaList.sort(
(s1, s2) -> {
return s1.getSchemaName() == null
? -1
@@ -258,7 +256,7 @@ public class DatabaseMetaInformation {
});
// Save for later...
- setSchemas(schemaList.toArray(new Schema[schemaList.size()]));
+ setSchemas(schemaList.toArray(new Schema[0]));
}
monitor.worked(1);
if (monitor.isCanceled()) {
@@ -309,7 +307,6 @@ public class DatabaseMetaInformation {
BaseMessages.getString(PKG,
"DatabaseMeta.Error.UnableRetrieveDbInfo"), e);
} finally {
monitor.subTask(BaseMessages.getString(PKG,
"DatabaseMeta.Info.ClosingDbConnection"));
- db.disconnect();
monitor.done();
}
}
diff --git
a/core/src/main/java/org/apache/hop/core/database/DatabasePluginType.java
b/core/src/main/java/org/apache/hop/core/database/DatabasePluginType.java
index 49c736bb19..c8903182ba 100644
--- a/core/src/main/java/org/apache/hop/core/database/DatabasePluginType.java
+++ b/core/src/main/java/org/apache/hop/core/database/DatabasePluginType.java
@@ -22,7 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.hop.core.Const;
import org.apache.hop.core.plugins.BasePluginType;
-/** This class represents the transform plugin type. */
+/** This class represents the database plugin type. */
public class DatabasePluginType extends BasePluginType<DatabaseMetaPlugin> {
private static DatabasePluginType pluginType;
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNode.java
b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeNode.java
similarity index 73%
rename from
ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNode.java
rename to ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeNode.java
index 8a936c9f82..46d100fcd3 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNode.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeNode.java
@@ -15,9 +15,8 @@
* limitations under the License.
*/
-package org.apache.hop.ui.hopgui.perspective.database;
+package org.apache.hop.ui.core.database;
-import java.util.Collection;
import lombok.Getter;
/** Data stored on a connection-tree item. */
@@ -73,33 +72,4 @@ public class DatabaseTreeNode {
public boolean isTableLike() {
return kind == Kind.TABLE || kind == Kind.VIEW || kind == Kind.SYNONYM;
}
-
- /**
- * Classify a schema object so views (and synonyms) can use a distinct tree
icon.
- *
- * @param name object name
- * @param views view names in the same schema (any case)
- * @param synonyms synonym names in the same schema (any case)
- */
- public static Kind kindOf(String name, Collection<String> views,
Collection<String> synonyms) {
- if (containsIgnoreCase(views, name)) {
- return Kind.VIEW;
- }
- if (containsIgnoreCase(synonyms, name)) {
- return Kind.SYNONYM;
- }
- return Kind.TABLE;
- }
-
- static boolean containsIgnoreCase(Collection<String> names, String name) {
- if (names == null || name == null) {
- return false;
- }
- for (String candidate : names) {
- if (name.equalsIgnoreCase(candidate)) {
- return true;
- }
- }
- return false;
- }
}
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeUtil.java
b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeUtil.java
new file mode 100644
index 0000000000..69cde818d7
--- /dev/null
+++ b/ui/src/main/java/org/apache/hop/ui/core/database/DatabaseTreeUtil.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.hop.ui.core.database;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import org.apache.hop.ui.core.database.DatabaseTreeNode.Kind;
+import org.apache.hop.ui.core.gui.GuiResource;
+import org.eclipse.swt.graphics.Image;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Utility class for sharing functions between the Database perspective and
the Database Explorer
+ * dialog.
+ */
+public class DatabaseTreeUtil {
+
+ private DatabaseTreeUtil() {
+ // Utility class
+ }
+
+ /**
+ * Classify a schema object so views (and synonyms) can use a distinct tree
icon.
+ *
+ * @param name object name
+ * @param views view names in the same schema (any case)
+ * @param synonyms synonym names in the same schema (any case)
+ */
+ public static Kind kindOf(String name, Collection<String> views,
Collection<String> synonyms) {
+ if (containsIgnoreCase(views, name)) {
+ return Kind.VIEW;
+ }
+ if (containsIgnoreCase(synonyms, name)) {
+ return Kind.SYNONYM;
+ }
+ return Kind.TABLE;
+ }
+
+ public static boolean containsIgnoreCase(
+ @Nullable Collection<String> names, @Nullable String name) {
+ if (names == null || name == null) {
+ return false;
+ }
+ for (String candidate : names) {
+ if (name.equalsIgnoreCase(candidate)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Collection<String> namesForSchema(
+ Map<String, Collection<String>> map, String schemaName) {
+ if (map == null || map.isEmpty()) {
+ return List.of();
+ }
+ if (schemaName != null) {
+ Collection<String> exact = map.get(schemaName);
+ if (exact != null) {
+ return exact;
+ }
+ for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
+ if (schemaName.equalsIgnoreCase(entry.getKey()) && entry.getValue() !=
null) {
+ return entry.getValue();
+ }
+ }
+ }
+ Collection<String> empty = map.get("");
+ if (empty != null) {
+ return empty;
+ }
+ Collection<String> missing = map.get(null);
+ return missing != null ? missing : List.of();
+ }
+
+ public static Image imageFor(DatabaseTreeNode.Kind kind) {
+ GuiResource resources = GuiResource.getInstance();
+ return switch (kind) {
+ case VIEW -> resources.getImageView();
+ case SYNONYM -> resources.getImageSynonym();
+ default -> resources.getImageTable();
+ };
+ }
+}
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/DatabaseExplorerDialog.java
b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/DatabaseExplorerDialog.java
index 60827710af..76ad966459 100644
---
a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/DatabaseExplorerDialog.java
+++
b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/DatabaseExplorerDialog.java
@@ -18,12 +18,13 @@
package org.apache.hop.ui.core.database.dialog;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
-import java.util.Objects;
import lombok.Getter;
import lombok.Setter;
-import org.apache.commons.lang3.StringUtils;
import org.apache.hop.core.Const;
+import org.apache.hop.core.DbCache;
import org.apache.hop.core.Props;
import org.apache.hop.core.database.Catalog;
import org.apache.hop.core.database.Database;
@@ -32,6 +33,9 @@ import org.apache.hop.core.database.DatabaseMetaInformation;
import org.apache.hop.core.database.Schema;
import org.apache.hop.core.exception.HopDatabaseException;
import org.apache.hop.core.gui.plugin.GuiPlugin;
+import org.apache.hop.core.gui.plugin.key.GuiKeyboardShortcut;
+import org.apache.hop.core.gui.plugin.key.GuiOsxKeyboardShortcut;
+import org.apache.hop.core.gui.plugin.menu.GuiMenuElement;
import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElement;
import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElementType;
import org.apache.hop.core.logging.ILogChannel;
@@ -39,43 +43,45 @@ import org.apache.hop.core.logging.ILoggingObject;
import org.apache.hop.core.logging.LogChannel;
import org.apache.hop.core.logging.LoggingObject;
import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.search.SearchMatcher;
+import org.apache.hop.core.util.Utils;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.i18n.BaseMessages;
-import org.apache.hop.ui.core.ConstUi;
+import org.apache.hop.ui.core.FormDataBuilder;
import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.database.DatabaseTreeNode;
+import org.apache.hop.ui.core.database.DatabaseTreeUtil;
+import org.apache.hop.ui.core.dialog.BaseDialog;
import org.apache.hop.ui.core.dialog.EnterSelectionDialog;
import org.apache.hop.ui.core.dialog.ErrorDialog;
import org.apache.hop.ui.core.dialog.MessageBox;
import org.apache.hop.ui.core.dialog.ShowRowsDialog;
import org.apache.hop.ui.core.dialog.TransformFieldsDialog;
+import org.apache.hop.ui.core.gui.GuiMenuWidgets;
import org.apache.hop.ui.core.gui.GuiResource;
import org.apache.hop.ui.core.gui.GuiToolbarWidgets;
import org.apache.hop.ui.core.gui.IToolbarContainer;
import org.apache.hop.ui.core.gui.WindowProperty;
import org.apache.hop.ui.core.widget.HopTree;
import org.apache.hop.ui.hopgui.HopGui;
+import org.apache.hop.ui.hopgui.HopGuiKeyHandler;
import org.apache.hop.ui.hopgui.ToolbarFacade;
-import org.apache.hop.ui.hopgui.perspective.database.DatabaseWorkbenchDialog;
import org.apache.hop.ui.pipeline.transform.BaseTransformDialog;
import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FormAttachment;
-import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Dialog;
-import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
+import org.jspecify.annotations.Nullable;
/**
* This dialog represents an explorer type of interface on a given database
connection. It shows the
@@ -85,31 +91,39 @@ import org.eclipse.swt.widgets.TreeItem;
@GuiPlugin
public class DatabaseExplorerDialog extends Dialog {
private static final Class<?> PKG = DatabaseExplorerDialog.class;
-
+ public static final String GUI_PLUGIN_CONTEXT_MENU_PARENT_ID =
+ "DatabaseExplorerDialog-ContextMenu";
+ public static final String GUI_PLUGIN_SEARCHBAR_PARENT_ID =
"DatabaseExplorerDialog-SearchBar";
public static final String GUI_PLUGIN_TOOLBAR_PARENT_ID =
"DatabaseExplorerDialog-Toolbar";
- public static final String TOOLBAR_ITEM_EXPAND_ALL =
"DatabaseExplorer-ToolBar-10100-ExpandAll";
- public static final String TOOLBAR_ITEM_COLLAPSE_ALL =
- "DatabaseExplorer-ToolBar-10200-CollapseAll";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_100 =
- "DatabaseExplorerDialog.Menu.Preview100";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_N =
- "DatabaseExplorerDialog.Menu.PreviewN";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_SIZE =
- "DatabaseExplorerDialog.Menu.ShowSize";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_LAYOUT =
- "DatabaseExplorerDialog.Menu.ShowLayout";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_OPEN_SQL =
- "DatabaseExplorerDialog.Menu.OpenSQL";
- public static final String CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDL =
- "DatabaseExplorerDialog.Menu.GenDDL";
- public static final String
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDLOTHER_CONN =
- "DatabaseExplorerDialog.Menu.GenDDLOtherConn";
- private final ILogChannel log;
- private final PropsUi props;
- private DatabaseMeta dbMeta;
- private final IVariables variables;
- private final ILoggingObject loggingObject;
+ public static final String TOOLBAR_ITEM_REGEX =
"10000-DatabaseExplorerDialog-ToolBar-Regex";
+ public static final String TOOLBAR_ITEM_REFRESH =
"DatabaseExplorerDialog-ToolBar-10000-Refresh";
+ public static final String TOOLBAR_ITEM_EXPAND_ALL =
+ "DatabaseExplorerDialog-ToolBar-10010-ExpandAll";
+ public static final String TOOLBAR_ITEM_COLLAPSE_ALL =
+ "DatabaseExplorerDialog-ToolBar-10020-CollapseAll";
+ public static final String TOOLBAR_ITEM_PREVIEW =
"DatabaseExplorerDialog-Toolbar-10050-Preview";
+ public static final String TOOLBAR_ITEM_SHOW_LAYOUT =
+ "DatabaseExplorerDialog-Toolbar-10060-ShowLayout";
+ public static final String TOOLBAR_ITEM_SQL_SELECT =
+ "DatabaseExplorerDialog-Toolbar-10070-SqlSelect";
+
+ public static final String CONTEXT_MENU_PREVIEW_100 =
+ "DatabaseExplorerDialog-ContextMenu-10010-Preview100";
+ public static final String CONTEXT_MENU_PREVIEW_N =
+ "DatabaseExplorerDialog-ContextMenu-10020-PreviewN";
+ public static final String CONTEXT_MENU_SHOW_SIZE =
+ "DatabaseExplorerDialog-ContextMenu-10030-ShowSize";
+ public static final String CONTEXT_MENU_SHOW_LAYOUT =
+ "DatabaseExplorerDialog-ContextMenu-10040-ShowLayout";
+ public static final String CONTEXT_MENU_DDL =
+ "DatabaseExplorerDialog-ContextMenu-10050-GenerateDdl";
+ public static final String CONTEXT_MENU_DDL_OTHER =
+ "DatabaseExplorerDialog-ContextMenu-10060-GenerateDdlOther";
+ public static final String CONTEXT_MENU_SQL_SELECT =
+ "DatabaseExplorerDialog-ContextMenu-10070-SqlSelect";
+ public static final String CONTEXT_MENU_SQL_TRUNCATE =
+ "DatabaseExplorerDialog-ContextMenu-10080-SqlTruncate";
private static final String STRING_CATALOG =
BaseMessages.getString(PKG, "DatabaseExplorerDialog.Catalogs.Label");
@@ -122,107 +136,97 @@ public class DatabaseExplorerDialog extends Dialog {
private static final String STRING_SYNONYMS =
BaseMessages.getString(PKG, "DatabaseExplorerDialog.Synonyms.Label");
- private final Shell parentShell;
- private Shell shell;
- private Tree wTree;
- private TreeItem tiTree;
-
- /** Updated on SWT.Expand/Collapse; used to detect native ">" handling vs
DPI miss. */
- private long lastTreeExpandCollapseNanos;
+ private static final int FILTER_DEBOUNCE_MS = 250;
- @Getter @Setter private String tableName;
+ /** Debounced search action so we don't rebuild the tree on every keystroke.
*/
+ private final Runnable filterRunnable = this::updateTree;
- private final boolean justLook;
- @Getter @Setter private String selectedSchema;
- @Setter private String selectedTable;
+ private final ILogChannel log;
+ private final DatabaseMeta databaseMeta;
+ private final IVariables variables;
+ private final DbCache dbCache;
+ private final ILoggingObject loggingObject;
private final List<DatabaseMeta> databases;
- @Getter @Setter private boolean splitSchemaAndTable;
- @Getter @Setter private String schemaName;
- private Composite buttonsComposite;
- private Button wOk;
- private Button bPrev;
- private Button bPrevN;
- private Button bCount;
- private Button bShow;
- private Button bDDL;
- private Button bDDL2;
- private Button bSql;
- private String activeSchemaTable;
- private Button bTruncate;
-
- private Control toolBar;
+ private final boolean justLook;
+
+ private Shell shell;
+ private Tree wTree;
+ private TreeItem connectionItem;
+ private Text wSearch;
+ private GuiToolbarWidgets searchBarWidgets;
+ private GuiToolbarWidgets toolBarWidgets;
+ private GuiMenuWidgets menuWidgets;
+ private SearchMatcher filter;
+ private boolean filterUseRegEx;
+ private String selectedSchemaName;
+ private String selectedTableName;
+ @Setter @Getter private boolean splitSchemaAndTable;
+ private DatabaseMetaInformation databaseMetaInformation;
public DatabaseExplorerDialog(
Shell parentShell,
int style,
IVariables variables,
- DatabaseMeta conn,
+ DatabaseMeta databaseMeta,
List<DatabaseMeta> databases) {
- this(parentShell, style, variables, conn, databases, false, true);
+ this(parentShell, style, variables, databaseMeta, databases, false, true);
}
public DatabaseExplorerDialog(
- Shell parentShell,
+ Shell parent,
int style,
IVariables variables,
- DatabaseMeta conn,
+ DatabaseMeta databaseMeta,
List<DatabaseMeta> databases,
boolean look,
boolean splitSchemaAndTable) {
- super(parentShell, style);
- this.parentShell = parentShell;
- this.dbMeta = conn;
+ super(parent, style);
+ this.databaseMeta = databaseMeta;
this.variables = variables;
this.databases = databases;
this.justLook = look;
this.splitSchemaAndTable = splitSchemaAndTable;
this.loggingObject = new LoggingObject("Database Explorer");
- selectedSchema = null;
- selectedTable = null;
-
- props = PropsUi.getInstance();
+ filterUseRegEx = false;
+ selectedSchemaName = null;
+ selectedTableName = null;
log = new LogChannel("DBExplorer");
+ dbCache = DbCache.getInstance();
}
public boolean open() {
- tableName = null;
-
if (Const.isLinux()) {
shell =
new Shell(
- parentShell,
+ getParent(),
SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX |
SWT.MIN);
} else {
- shell = new Shell(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX |
SWT.MIN);
+ shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX |
SWT.MIN);
}
PropsUi.setLook(shell);
shell.setImage(GuiResource.getInstance().getImageDatabase());
-
- shell.setText(BaseMessages.getString(PKG, "DatabaseExplorerDialog.Title",
dbMeta.toString()));
+ // Do not include the connection name in the title (to save/restore the
dialog box dimensions
+ // once)
+ shell.setText(BaseMessages.getString(PKG, "DatabaseExplorerDialog.Title"));
FormLayout formLayout = new FormLayout();
formLayout.marginWidth = PropsUi.getFormMargin();
formLayout.marginHeight = PropsUi.getFormMargin();
-
shell.setLayout(formLayout);
+ shell.setMinimumSize(200, 400);
int margin = PropsUi.getMargin();
// Main buttons at the bottom
//
List<Button> buttons = new ArrayList<>();
- wOk = new Button(shell, SWT.PUSH);
+ Button wOk = new Button(shell, SWT.PUSH);
wOk.setText(BaseMessages.getString(PKG, "System.Button.OK"));
wOk.addListener(SWT.Selection, e -> ok());
buttons.add(wOk);
shell.setDefaultButton(wOk);
- Button wRefresh = new Button(shell, SWT.PUSH);
- wRefresh.setText(BaseMessages.getString(PKG, "System.Button.Refresh"));
- wRefresh.addListener(SWT.Selection, e -> getData());
- buttons.add(wRefresh);
-
if (!justLook) {
Button wCancel = new Button(shell, SWT.PUSH);
wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
@@ -231,257 +235,125 @@ public class DatabaseExplorerDialog extends Dialog {
}
BaseTransformDialog.positionBottomButtons(shell, buttons.toArray(new
Button[0]), margin, null);
- // Add a toolbar
- //
- IToolbarContainer toolBarContainer =
+ // Create toolbar for search options at the top right
+ IToolbarContainer searchBarContainer =
ToolbarFacade.createToolbarContainer(shell, SWT.WRAP | SWT.LEFT |
SWT.HORIZONTAL);
- toolBar = toolBarContainer.getControl();
- GuiToolbarWidgets toolBarWidgets = new GuiToolbarWidgets();
+ searchBarWidgets = new GuiToolbarWidgets();
+ searchBarWidgets.registerGuiPluginObject(this);
+ searchBarWidgets.createToolbarWidgets(searchBarContainer,
GUI_PLUGIN_SEARCHBAR_PARENT_ID);
+ Control searchBar = searchBarContainer.getControl();
+ searchBar.setLayoutData(FormDataBuilder.builder().top().right().build());
+ PropsUi.setLook(searchBar, Props.WIDGET_STYLE_TOOLBAR);
+
+ // Create search/filter text box at the top left
+ wSearch = new Text(shell, SWT.SEARCH | SWT.ICON_SEARCH | SWT.ICON_CANCEL |
SWT.BORDER);
+ wSearch.setMessage(BaseMessages.getString(PKG,
"DatabaseExplorerDialog.Search.Placeholder"));
+
wSearch.setLayoutData(FormDataBuilder.builder().top().left().right(searchBar,
-margin).build());
+ wSearch.setData(BaseDialog.NO_DEFAULT_HANDLER, "Nop");
+ wSearch.addListener(SWT.Modify, e -> filterTree());
+ wSearch.addListener(SWT.DefaultSelection, e -> updateTree());
+ PropsUi.setLook(wSearch, Props.WIDGET_STYLE_TOOLBAR);
+
+ // Create composite
+ Composite composite = new Composite(shell, SWT.BORDER);
+ composite.setLayout(new FormLayout());
+ composite.setLayoutData(
+ FormDataBuilder.builder()
+ .top(searchBar, margin)
+ .bottom(wOk, -2 * margin)
+ .fullWidth()
+ .build());
+ PropsUi.setLook(composite);
+
+ // Create toolbar for tree actions
+ IToolbarContainer toolBarContainer =
+ ToolbarFacade.createToolbarContainer(composite, SWT.WRAP | SWT.LEFT |
SWT.HORIZONTAL);
+ toolBarWidgets = new GuiToolbarWidgets();
toolBarWidgets.registerGuiPluginObject(this);
toolBarWidgets.createToolbarWidgets(toolBarContainer,
GUI_PLUGIN_TOOLBAR_PARENT_ID);
- FormData layoutData = new FormData();
- layoutData.top = new FormAttachment(0, 0);
- layoutData.left = new FormAttachment(0, 0);
- layoutData.right = new FormAttachment(100, 0);
- toolBar.setLayoutData(layoutData);
- toolBar.pack();
+ Control toolBar = toolBarContainer.getControl();
+ toolBar.setLayoutData(FormDataBuilder.builder().top().fullWidth().build());
PropsUi.setLook(toolBar, Props.WIDGET_STYLE_TOOLBAR);
- addRightButtons();
- refreshButtons(null);
-
- // Tree /*| (multiple?SWT.CHECK:SWT.NONE)*/
- wTree = new HopTree(shell, SWT.SINGLE | SWT.BORDER);
+ // Create tree
+ wTree = new HopTree(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
+ wTree.setLayoutData(
+ FormDataBuilder.builder().top(toolBar,
margin).bottom().fullWidth().build());
+ wTree.addListener(SWT.DefaultSelection, this::openTreeItem);
+ wTree.addListener(SWT.Selection, e -> updateGui());
PropsUi.setLook(wTree);
- FormData fdTree = new FormData();
- // To the right of the label
- fdTree.left = new FormAttachment(0, 0);
- fdTree.top = new FormAttachment(toolBar, margin);
- fdTree.right = new FormAttachment(buttonsComposite, -margin);
- fdTree.bottom = new FormAttachment(wOk, -2 * margin);
- wTree.setLayoutData(fdTree);
-
- if (!getData()) {
- if (shell != null && !shell.isDisposed()) {
- shell.dispose();
- }
- return false;
- }
- wTree.addListener(SWT.Selection, e -> refreshButtons(getSchemaTable()));
- wTree.addListener(SWT.DefaultSelection, this::openSchema);
- wTree.addListener(SWT.Expand, e -> lastTreeExpandCollapseNanos =
System.nanoTime());
- wTree.addListener(SWT.Collapse, e -> lastTreeExpandCollapseNanos =
System.nanoTime());
- wTree.addListener(SWT.MouseDown, this::handleTreeMouseDown);
- shell.addListener(SWT.Close, e -> cancel());
+ // Create context menu
+ Menu menu = new Menu(wTree);
+ menuWidgets = new GuiMenuWidgets();
+ menuWidgets.registerGuiPluginObject(this);
+ menuWidgets.createMenuWidgets(GUI_PLUGIN_CONTEXT_MENU_PARENT_ID, shell,
menu);
+ wTree.setMenu(menu);
+ wTree.addListener(SWT.MenuDetect, e -> updateGui());
- // Prevent resizing below the complete control layout (notably right-side
action buttons).
- Point minSize = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
- shell.setMinimumSize(minSize);
- BaseTransformDialog.setSize(shell);
+ // So shortcut work and we're tried before the active perspective
+ HopGuiKeyHandler keyHandler = HopGuiKeyHandler.getInstance();
+ keyHandler.addParentObjectToHandle(this, shell);
+ HopGui.getInstance().replaceKeyboardShortcutListeners(shell, keyHandler);
- shell.open();
+ refresh();
- // Handle the event loop until we're done with this shell...
- //
- Display display = shell.getDisplay();
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch()) {
- display.sleep();
- }
- }
+ updateGui();
+
+ wSearch.setFocus();
- return tableName != null;
+ BaseDialog.defaultShellHandling(shell, c -> ok(), c -> cancel());
+
+ return selectedTableName != null;
}
- private void cancel() {
- log.logBasic("SelectTableDialog", "CANCEL SelectTableDialog", null);
- dbMeta = null;
+ public void cancel() {
+ selectedSchemaName = null;
+ selectedTableName = null;
dispose();
}
- private void addRightButtons() {
- buttonsComposite = new Composite(shell, SWT.NONE);
- PropsUi.setLook(buttonsComposite);
- buttonsComposite.setLayout(new FormLayout());
-
- activeSchemaTable = null;
-
- bPrev = new Button(buttonsComposite, SWT.PUSH);
- bPrev.setText(
- BaseMessages.getString(
- PKG,
- CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_100,
- Const.NVL(activeSchemaTable, "?")));
- bPrev.setEnabled(activeSchemaTable != null);
- bPrev.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- previewTable(activeSchemaTable);
- }
- });
- FormData prevData = new FormData();
- prevData.left = new FormAttachment(0, 0);
- prevData.right = new FormAttachment(100, 0);
- prevData.top = new FormAttachment(0, 0);
- bPrev.setLayoutData(prevData);
-
- bPrevN = new Button(buttonsComposite, SWT.PUSH);
- bPrevN.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_N,
Const.NVL(activeSchemaTable, "?")));
- bPrevN.setEnabled(activeSchemaTable != null);
- bPrevN.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- previewTable(activeSchemaTable);
- }
- });
- FormData prevNData = new FormData();
- prevNData.left = new FormAttachment(0, 0);
- prevNData.right = new FormAttachment(100, 0);
- prevNData.top = new FormAttachment(bPrev, PropsUi.getMargin());
- bPrevN.setLayoutData(prevNData);
-
- bCount = new Button(buttonsComposite, SWT.PUSH);
- bCount.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_SIZE,
Const.NVL(activeSchemaTable, "?")));
- bCount.setEnabled(activeSchemaTable != null);
- bCount.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- showCount(activeSchemaTable);
- }
- });
- FormData countData = new FormData();
- countData.left = new FormAttachment(0, 0);
- countData.right = new FormAttachment(100, 0);
- countData.top = new FormAttachment(bPrevN, PropsUi.getMargin());
- bCount.setLayoutData(countData);
-
- bShow = new Button(buttonsComposite, SWT.PUSH);
- bShow.setText(
- BaseMessages.getString(
- PKG,
- CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_LAYOUT,
- Const.NVL(activeSchemaTable, "?")));
- bShow.setEnabled(activeSchemaTable != null);
- bShow.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- showTable(activeSchemaTable);
- }
- });
- FormData showData = new FormData();
- showData.left = new FormAttachment(0, 0);
- showData.right = new FormAttachment(100, 0);
- showData.top = new FormAttachment(bCount, PropsUi.getMargin() * 7);
- bShow.setLayoutData(showData);
-
- bDDL = new Button(buttonsComposite, SWT.PUSH);
- bDDL.setText(BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDL));
- bDDL.setEnabled(activeSchemaTable != null);
- bDDL.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getDDL(activeSchemaTable);
- }
- });
- FormData ddlData = new FormData();
- ddlData.left = new FormAttachment(0, 0);
- ddlData.right = new FormAttachment(100, 0);
- ddlData.top = new FormAttachment(bShow, PropsUi.getMargin());
- bDDL.setLayoutData(ddlData);
-
- bDDL2 = new Button(buttonsComposite, SWT.PUSH);
- bDDL2.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDLOTHER_CONN));
- bDDL2.setEnabled(activeSchemaTable != null && databases != null);
- bDDL2.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getDDLForOther(activeSchemaTable);
- }
- });
- FormData ddl2Data = new FormData();
- ddl2Data.left = new FormAttachment(0, 0);
- ddl2Data.right = new FormAttachment(100, 0);
- ddl2Data.top = new FormAttachment(bDDL, PropsUi.getMargin());
- bDDL2.setLayoutData(ddl2Data);
-
- bSql = new Button(buttonsComposite, SWT.PUSH);
- bSql.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_OPEN_SQL,
Const.NVL(activeSchemaTable, "?")));
- bSql.setEnabled(activeSchemaTable != null);
- bSql.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getSql(activeSchemaTable);
- }
- });
- FormData sqlData = new FormData();
- sqlData.left = new FormAttachment(0, 0);
- sqlData.right = new FormAttachment(100, 0);
- sqlData.top = new FormAttachment(bDDL2, PropsUi.getMargin());
- bSql.setLayoutData(sqlData);
-
- bTruncate = new Button(buttonsComposite, SWT.PUSH);
- bTruncate.setText(
- BaseMessages.getString(
- PKG, "DatabaseExplorerDialog.Menu.Truncate",
Const.NVL(activeSchemaTable, "?")));
- bTruncate.setEnabled(activeSchemaTable != null);
- bTruncate.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getTruncate(activeSchemaTable);
- }
- });
- FormData truncateData = new FormData();
- truncateData.left = new FormAttachment(0, 0);
- truncateData.right = new FormAttachment(100, 0);
- truncateData.top = new FormAttachment(bSql, PropsUi.getMargin());
- bTruncate.setLayoutData(truncateData);
-
- FormData fdComposite = new FormData();
- fdComposite.right = new FormAttachment(100, 0);
- // Attach to the toolbar control (not a pixel snapshot of its height at
creation time).
- fdComposite.top = new FormAttachment(toolBar, 0);
- fdComposite.bottom = new FormAttachment(wOk, -2 * PropsUi.getMargin());
- buttonsComposite.setLayoutData(fdComposite);
+ @GuiToolbarElement(
+ root = GUI_PLUGIN_SEARCHBAR_PARENT_ID,
+ id = TOOLBAR_ITEM_REGEX,
+ toolTip = "i18n::DatabaseExplorerDialog.RegEx.Tooltip",
+ type = GuiToolbarElementType.BUTTON,
+ image = "ui/images/regex.svg")
+ public void filterUseRegEx() {
+ this.filterUseRegEx = !this.filterUseRegEx;
+ // Update the button icon
+ updateGui();
+ // Apply the filter
+ updateTree();
}
@GuiToolbarElement(
root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
id = TOOLBAR_ITEM_EXPAND_ALL,
- toolTip = "i18n::DatabaseExplorerDialog.Toolbar.ExpandAll.Tooltip",
+ toolTip = "i18n::System.Tooltip.ExpandAll",
type = GuiToolbarElementType.BUTTON,
- image = "ui/images/expand-all.svg")
+ image = "ui/images/expand-all.svg",
+ separator = true)
+ @GuiKeyboardShortcut(control = true, key = '+')
+ @GuiOsxKeyboardShortcut(command = true, key = '+')
public void expandAll() {
- expandAllItems(wTree.getItems(), true);
+ expandAllItems(connectionItem.getItems(), true);
}
@GuiToolbarElement(
root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
id = TOOLBAR_ITEM_COLLAPSE_ALL,
- toolTip = "i18n::DatabaseExplorerDialog.Toolbar.CollapseAll.Tooltip",
+ toolTip = "i18n::System.Tooltip.CollapseALl",
type = GuiToolbarElementType.BUTTON,
image = "ui/images/collapse-all.svg")
+ @GuiKeyboardShortcut(control = true, key = '-')
+ @GuiOsxKeyboardShortcut(command = true, key = '-')
public void collapseAll() {
- expandAllItems(wTree.getItems(), false);
+ expandAllItems(connectionItem.getItems(), false);
}
- private void expandAllItems(TreeItem[] treeitems, boolean expand) {
- for (TreeItem item : treeitems) {
+ private void expandAllItems(TreeItem[] items, boolean expand) {
+ for (TreeItem item : items) {
item.setExpanded(expand);
if (item.getItemCount() > 0) {
expandAllItems(item.getItems(), expand);
@@ -489,368 +361,374 @@ public class DatabaseExplorerDialog extends Dialog {
}
}
- private void refreshButtons(String table) {
- // Avoid setText/layout while expanding folders: Windows DPI often
misaligns the native
- // expander hit target, and synchronous label updates during Selection can
make clicks feel
- // dead unless they land in the tiny gap between ">" and the folder icon.
- boolean tableChanged = !Objects.equals(activeSchemaTable, table);
- activeSchemaTable = table;
- boolean hasTable = table != null;
- boolean canGenerateDdlForOther = hasTable && databases != null;
-
- if (tableChanged) {
- bPrev.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_100,
Const.NVL(table, "?")));
- bPrevN.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_N,
Const.NVL(table, "?")));
- bCount.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_SIZE,
Const.NVL(table, "?")));
- bShow.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_LAYOUT,
Const.NVL(table, "?")));
- bDDL.setText(BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDL));
- bDDL2.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDLOTHER_CONN));
- bSql.setText(
- BaseMessages.getString(
- PKG, CONST_DATABASE_EXPLORER_DIALOG_MENU_OPEN_SQL,
Const.NVL(table, "?")));
- bTruncate.setText(
- BaseMessages.getString(
- PKG, "DatabaseExplorerDialog.Menu.Truncate", Const.NVL(table,
"?")));
+ @GuiToolbarElement(
+ root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
+ id = TOOLBAR_ITEM_REFRESH,
+ toolTip = "i18n::System.Button.Refresh",
+ type = GuiToolbarElementType.BUTTON,
+ image = "ui/images/refresh.svg")
+ @GuiKeyboardShortcut(key = SWT.F5)
+ @GuiOsxKeyboardShortcut(key = SWT.F5)
+ public void refresh() {
+ GetDatabaseInfoProgressDialog dialog =
+ new GetDatabaseInfoProgressDialog(shell, variables, databaseMeta);
+ this.databaseMetaInformation = dialog.open();
+ updateTree();
+ }
+
+ public void updateGui() {
+ // Update the regex filter icons in the search bar
+ ToolItem item = searchBarWidgets.findToolItem(TOOLBAR_ITEM_REGEX);
+ if (item != null && !item.isDisposed()) {
+ if (filterUseRegEx) {
+ item.setImage(GuiResource.getInstance().getImageRegex());
+ } else {
+ item.setImage(GuiResource.getInstance().getImageRegexDisabled());
+ }
}
- bPrev.setEnabled(hasTable);
- bPrevN.setEnabled(hasTable);
- bCount.setEnabled(hasTable);
- bShow.setEnabled(hasTable);
- bDDL.setEnabled(hasTable);
- bDDL2.setEnabled(canGenerateDdlForOther);
- bSql.setEnabled(hasTable);
- bTruncate.setEnabled(hasTable);
+ DatabaseTreeNode node = getSelectedNode();
+ boolean isTable = node != null && node.isTableLike();
+ toolBarWidgets.enableToolbarItem(TOOLBAR_ITEM_PREVIEW, isTable);
+ toolBarWidgets.enableToolbarItem(TOOLBAR_ITEM_SHOW_LAYOUT, isTable);
+ toolBarWidgets.enableToolbarItem(TOOLBAR_ITEM_SQL_SELECT, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_PREVIEW_100, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_PREVIEW_N, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_SHOW_SIZE, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_SHOW_LAYOUT, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_DDL, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_DDL_OTHER, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_SQL_SELECT, isTable);
+ menuWidgets.enableMenuItem(CONTEXT_MENU_SQL_TRUNCATE, isTable);
+ }
+
+ private SearchMatcher createSearchMatcher() {
+ if (wSearch != null && !wSearch.isDisposed()) {
+ String search = wSearch.getText();
+ if (!Utils.isEmpty(search)) {
+ return new SearchMatcher(search, false, filterUseRegEx, false);
+ }
+ }
+ return null; // new SearchMatcher("", false, false, false);
+ }
- if (!tableChanged || shell == null || shell.isDisposed()) {
+ /** Filter the tree based on search text, debounced so we don't rebuild on
every keystroke. */
+ protected void filterTree() {
+ if (shell == null || shell.isDisposed()) {
return;
}
- Display display = shell.getDisplay();
- display.asyncExec(
- () -> {
- if (shell == null || shell.isDisposed()) {
- return;
- }
- buttonsComposite.layout(true, true);
- shell.layout(true, false);
- });
+ shell.getDisplay().timerExec(FILTER_DEBOUNCE_MS, filterRunnable);
}
- private boolean getData() {
- GetDatabaseInfoProgressDialog gdipd =
- new GetDatabaseInfoProgressDialog(shell, variables, dbMeta);
- DatabaseMetaInformation dmi = gdipd.open();
- if (dmi == null) {
- return false;
+ /** Update tree when refresh or filter changed */
+ private void updateTree() {
+ if (wTree.isDisposed()) {
+ return;
}
- disposeOldTreeRootIfPresent();
- createDatabaseRootTreeItem();
- addCatalogBranches(dmi);
- addSchemaBranches(dmi);
- TreeItem tiTab = addTablesBranch(dmi.getTables());
- TreeItem tiView = addViewsBranch(dmi.getViews());
- TreeItem tiSyn = addSynonymsBranch(dmi.getSynonyms());
- selectInitiallySelectedTable(tiTab, tiView, tiSyn);
- tiTree.setExpanded(true);
- return true;
- }
- private void disposeOldTreeRootIfPresent() {
- if (tiTree != null && !tiTree.isDisposed()) {
- tiTree.dispose();
+ shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+ wTree.setRedraw(false);
+
+ // Remove all previous items
+ wTree.removeAll();
+
+ // Create connection tree item
+ String connectionName = "";
+ Image image = GuiResource.getInstance().getImageDatabase();
+ if (databaseMeta != null) {
+ connectionName = databaseMeta.getName();
+ image = GuiResource.getInstance().getImage(databaseMeta.getIDatabase());
+ }
+ connectionItem = new TreeItem(wTree, SWT.NONE);
+ connectionItem.setImage(image);
+ connectionItem.setText(connectionName);
+ connectionItem.setData(DatabaseTreeNode.connection(connectionName, true));
+
+ if (databaseMetaInformation != null) {
+
+ // Create search filter
+ this.filter = createSearchMatcher();
+
+ if (!updateTreeSchemas()) {
+ if (!updateTreeCatalogs()) {
+ addFolder(
+ connectionItem,
+ connectionName,
+ STRING_TABLES,
+ databaseMetaInformation.getTables(),
+ DatabaseTreeNode.Kind.TABLE);
+ addFolder(
+ connectionItem,
+ connectionName,
+ STRING_VIEWS,
+ databaseMetaInformation.getViews(),
+ DatabaseTreeNode.Kind.VIEW);
+ addFolder(
+ connectionItem,
+ connectionName,
+ STRING_SYNONYMS,
+ databaseMetaInformation.getSynonyms(),
+ DatabaseTreeNode.Kind.SYNONYM);
+ }
+ }
}
- }
- private void createDatabaseRootTreeItem() {
- tiTree = new TreeItem(wTree, SWT.NONE);
- tiTree.setImage(GuiResource.getInstance().getImageDatabase());
- tiTree.setText(dbMeta == null ? "" : dbMeta.getName());
+ // Always expand the root item
+ connectionItem.setExpanded(true);
+
+ wTree.setRedraw(true);
+ shell.setCursor(null);
+ }
+
+ // Database support catalogs
+ private boolean updateTreeCatalogs() {
+ Catalog[] catalogs = databaseMetaInformation.getCatalogs();
+ if (catalogs != null && catalogs.length > 0) {
+ String connectionName = databaseMeta.getName();
+ for (Catalog catalog : catalogs) {
+ TreeItem catalogItem = new TreeItem(connectionItem, SWT.NONE);
+ catalogItem.setText(Const.NVL(catalog.getCatalogName(), ""));
+ catalogItem.setImage(GuiResource.getInstance().getImageFolder());
+ catalogItem.setData(DatabaseTreeNode.catalog(connectionName,
catalog.getCatalogName()));
+ addSchemaObjects(
+ catalogItem,
+ connectionName,
+ catalog.getCatalogName(),
+ catalog.getItems(),
+ databaseMetaInformation);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ // Database support schemas
+ private boolean updateTreeSchemas() {
+ Schema[] schemas = databaseMetaInformation.getSchemas();
+ if (schemas != null && schemas.length > 0) {
+ String connectionName = databaseMeta.getName();
+ for (Schema schema : schemas) {
+ if (schemaOrChildMatches(schema, databaseMetaInformation)) {
+ TreeItem schemaItem = new TreeItem(connectionItem, SWT.NONE);
+ schemaItem.setText(Const.NVL(schema.getSchemaName(), ""));
+ schemaItem.setImage(GuiResource.getInstance().getImageSchema());
+ schemaItem.setData(DatabaseTreeNode.schema(connectionName,
schema.getSchemaName()));
+ addSchemaObjects(
+ schemaItem,
+ connectionName,
+ schema.getSchemaName(),
+ schema.getItems(),
+ databaseMetaInformation);
+ }
+ }
+ return true;
+ }
+ return false;
}
- private void addCatalogBranches(DatabaseMetaInformation dmi) {
- Catalog[] catalogs = dmi.getCatalogs();
- if (catalogs == null) {
+ private void addFolder(
+ TreeItem parent,
+ String connectionName,
+ String folderName,
+ String[] names,
+ DatabaseTreeNode.Kind kind) {
+ if (names == null || names.length == 0) {
return;
}
- TreeItem tiCat = new TreeItem(tiTree, SWT.NONE);
- tiCat.setImage(GuiResource.getInstance().getImageFolder());
- tiCat.setText(STRING_CATALOG);
- for (Catalog catalog : catalogs) {
- TreeItem newCat = new TreeItem(tiCat, SWT.NONE);
- newCat.setImage(GuiResource.getInstance().getImageFolder());
- newCat.setText(catalog.getCatalogName());
- for (String catalogItemName : catalog.getItems()) {
- TreeItem ti = new TreeItem(newCat, SWT.NONE);
- ti.setImage(GuiResource.getInstance().getImageTable());
- ti.setText(catalogItemName);
- }
- }
+ TreeItem item = new TreeItem(parent, SWT.NONE);
+ item.setText(folderName);
+ item.setImage(GuiResource.getInstance().getImageFolder());
+ item.setData(DatabaseTreeNode.folder(connectionName, folderName));
+ addTables(item, connectionName, names, kind);
}
- private void addSchemaBranches(DatabaseMetaInformation dmi) {
- Schema[] schemas = dmi.getSchemas();
- if (schemas == null) {
+ private void addTables(
+ TreeItem parent, String connectionName, String[] names,
DatabaseTreeNode.Kind kind) {
+ if (names == null) {
return;
}
- TreeItem tiSch = new TreeItem(tiTree, SWT.NONE);
- tiSch.setImage(GuiResource.getInstance().getImageFolder());
- tiSch.setText(STRING_SCHEMAS);
- for (Schema schema : schemas) {
- TreeItem newSch = new TreeItem(tiSch, SWT.NONE);
- newSch.setImage(GuiResource.getInstance().getImageSchema());
- newSch.setText(schema.getSchemaName());
- for (String schemaItemName : schema.getItems()) {
- TreeItem ti = new TreeItem(newSch, SWT.NONE);
- ti.setImage(GuiResource.getInstance().getImageTable());
- ti.setText(schemaItemName);
+ boolean expanded = false;
+ for (String name : names) {
+ if (matchesFilter(name, null)) {
+ TreeItem item = new TreeItem(parent, SWT.NONE);
+ item.setText(name);
+ item.setImage(DatabaseTreeUtil.imageFor(kind));
+ item.setData(DatabaseTreeNode.table(kind, connectionName, null, name));
+
+ // Highlight selected item
+ if (name.equalsIgnoreCase(selectedTableName)) {
+ item.setFont(GuiResource.getInstance().getFontBold());
+ wTree.setSelection(item);
+ wTree.showItem(item);
+ expanded = true;
+ }
}
}
- }
-
- private TreeItem addTablesBranch(String[] tabnames) {
- if (tabnames == null) {
- return null;
- }
- TreeItem tiTab = new TreeItem(tiTree, SWT.NONE);
- tiTab.setImage(GuiResource.getInstance().getImageFolder());
- tiTab.setText(STRING_TABLES);
- for (String tabname : tabnames) {
- TreeItem newTab = new TreeItem(tiTab, SWT.NONE);
- newTab.setImage(GuiResource.getInstance().getImageTable());
- newTab.setText(tabname);
+ parent.setExpanded(expanded);
+ }
+
+ /**
+ * Tables, views and synonyms under a schema (or catalog). Views get {@code
view.svg} via {@link
+ * DatabaseTreeUtil#kindOf}.
+ */
+ private void addSchemaObjects(
+ TreeItem parent,
+ String connectionName,
+ String schemaName,
+ String[] items,
+ DatabaseMetaInformation info) {
+ Collection<String> views =
DatabaseTreeUtil.namesForSchema(info.getViewMap(), schemaName);
+ Collection<String> synonyms =
DatabaseTreeUtil.namesForSchema(info.getSynonymMap(), schemaName);
+ List<String> names = new ArrayList<>();
+ if (items != null) {
+ names.addAll(Arrays.asList(items));
}
- tiTab.setExpanded(true);
- return tiTab;
- }
-
- private TreeItem addViewsBranch(String[] views) {
- if (views == null) {
- return null;
- }
- TreeItem tiView = new TreeItem(tiTree, SWT.NONE);
- tiView.setImage(GuiResource.getInstance().getImageFolder());
- tiView.setText(STRING_VIEWS);
for (String view : views) {
- TreeItem newView = new TreeItem(tiView, SWT.NONE);
- newView.setImage(GuiResource.getInstance().getImageView());
- newView.setText(view);
- }
- return tiView;
- }
-
- private TreeItem addSynonymsBranch(String[] syn) {
- if (syn == null) {
- return null;
+ if (!DatabaseTreeUtil.containsIgnoreCase(names, view)) {
+ names.add(view);
+ }
}
- TreeItem tiSyn = new TreeItem(tiTree, SWT.NONE);
- tiSyn.setImage(GuiResource.getInstance().getImageFolder());
- tiSyn.setText(STRING_SYNONYMS);
- for (String s : syn) {
- TreeItem newSyn = new TreeItem(tiSyn, SWT.NONE);
- newSyn.setImage(GuiResource.getInstance().getImageSynonym());
- newSyn.setText(s);
+ for (String synonym : synonyms) {
+ if (!DatabaseTreeUtil.containsIgnoreCase(names, synonym)) {
+ names.add(synonym);
+ }
}
- return tiSyn;
- }
+ names.sort(String.CASE_INSENSITIVE_ORDER);
+ boolean expanded = false;
+ for (String name : names) {
+ if (matchesFilter(name, schemaName)) {
+ DatabaseTreeNode.Kind kind = DatabaseTreeUtil.kindOf(name, views,
synonyms);
+ TreeItem item = new TreeItem(parent, SWT.NONE);
+ item.setText(name);
+ item.setImage(DatabaseTreeUtil.imageFor(kind));
+ item.setData(DatabaseTreeNode.table(kind, connectionName, schemaName,
name));
+
+ // Highlight selected item
+ if (schemaName.equalsIgnoreCase(selectedSchemaName)
+ && name.equalsIgnoreCase(selectedTableName)) {
+ parent.setFont(GuiResource.getInstance().getFontBold());
+ item.setFont(GuiResource.getInstance().getFontBold());
+ wTree.setSelection(item);
+ wTree.showItem(item);
+ expanded = true;
+ }
- private void selectInitiallySelectedTable(TreeItem tiTab, TreeItem tiView,
TreeItem tiSyn) {
- if (StringUtils.isEmpty(selectedTable)) {
- return;
- }
- TreeItem ti = findTreeItemForInitialSelection(tiTab, tiView, tiSyn);
- if (ti != null) {
- wTree.setSelection(new TreeItem[] {ti});
- wTree.showSelection();
- if (dbMeta != null) {
- refreshButtons(
- dbMeta.getQuotedSchemaTableCombination(variables, selectedSchema,
selectedTable));
+ // If is filtered and an item match then expand parent
+ if (filter != null) {
+ expanded = true;
+ }
}
}
- selectedTable = null;
+ parent.setExpanded(expanded);
}
- private TreeItem findTreeItemForInitialSelection(
- TreeItem tiTab, TreeItem tiView, TreeItem tiSyn) {
- TreeItem ti = null;
- if (tiTab != null) {
- ti = ConstUi.findTreeItem(tiTab, selectedSchema, selectedTable);
+ private boolean matchesFilter(String name, String schemaName) {
+ if (filter == null) {
+ return true;
}
- if (ti == null && tiView != null) {
- ti = ConstUi.findTreeItem(tiView, selectedSchema, selectedTable);
- }
- if (ti == null) {
- ti = ConstUi.findTreeItem(tiTree, selectedSchema, selectedTable);
- }
- if (ti == null && tiSyn != null) {
- ti = ConstUi.findTreeItem(tiSyn, selectedSchema, selectedTable);
- }
- return ti;
+ return filter.matches(name) || filter.matches(schemaName);
}
- private String getSchemaTable() {
- TreeItem[] ti = wTree.getSelection();
- if (ti.length != 1) {
- return null;
+ private boolean schemaOrChildMatches(Schema schema, DatabaseMetaInformation
info) {
+ if (filter == null) {
+ return true;
}
- TreeItem parentItem = ti[0].getParentItem();
- if (parentItem == null) {
- return null;
+ if (filter.matches(schema.getSchemaName())) {
+ return true;
}
- String parentLabel = parentItem.getText();
- String itemText = ti[0].getText();
- if (ti[0].getItemCount() != 0) {
- return null;
- }
- if (isRootTableViewSynonymOrEmptyParent(parentLabel)) {
- return itemText;
+ if (schema.getItems() != null) {
+ for (String table : schema.getItems()) {
+ if (filter.matches(table)) {
+ return true;
+ }
+ }
}
- if (dbMeta == null) {
- return null;
+ for (String view : DatabaseTreeUtil.namesForSchema(info.getViewMap(),
schema.getSchemaName())) {
+ if (filter.matches(view)) {
+ return true;
+ }
}
- return dbMeta.getQuotedSchemaTableCombination(variables, parentLabel,
itemText);
+ return false;
}
- private static boolean isRootTableViewSynonymOrEmptyParent(String
parentLabel) {
- return parentLabel.equalsIgnoreCase(STRING_TABLES)
- || parentLabel.equalsIgnoreCase(STRING_VIEWS)
- || parentLabel.equalsIgnoreCase(STRING_SYNONYMS)
- || parentLabel.isEmpty();
- }
-
- public void setTreeMenu() {
- final String table = getSchemaTable();
- if (table != null) {
- Menu mTree = new Menu(shell, SWT.POP_UP);
-
- MenuItem miPrev = new MenuItem(mTree, SWT.PUSH);
- miPrev.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_100, table));
- miPrev.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- previewTable(table);
- }
- });
- MenuItem miPrevN = new MenuItem(mTree, SWT.PUSH);
- miPrevN.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_PREVIEW_N, table));
- miPrevN.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- previewTable(table);
- }
- });
- MenuItem miCount = new MenuItem(mTree, SWT.PUSH);
- miCount.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_SIZE, table));
- miCount.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- showCount(table);
- }
- });
-
- new MenuItem(mTree, SWT.SEPARATOR);
-
- MenuItem miShow = new MenuItem(mTree, SWT.PUSH);
- miShow.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_SHOW_LAYOUT, table));
- miShow.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- showTable(table);
- }
- });
- MenuItem miDDL = new MenuItem(mTree, SWT.PUSH);
- miDDL.setText(BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDL));
- miDDL.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getDDL(table);
- }
- });
- MenuItem miDDL2 = new MenuItem(mTree, SWT.PUSH);
- miDDL2.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_GEN_DDLOTHER_CONN));
- miDDL2.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getDDLForOther(table);
- }
- });
- miDDL2.setEnabled(databases != null);
- MenuItem miSql = new MenuItem(mTree, SWT.PUSH);
- miSql.setText(
- BaseMessages.getString(PKG,
CONST_DATABASE_EXPLORER_DIALOG_MENU_OPEN_SQL, table));
- miSql.addSelectionListener(
- new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- getSql(table);
- }
- });
-
- wTree.setMenu(mTree);
- } else {
- wTree.setMenu(null);
+ private @Nullable DatabaseTreeNode getSelectedNode() {
+ TreeItem[] selection = wTree.getSelection();
+ if (selection.length != 1) {
+ return null;
}
+ Object data = selection[0].getData();
+ return data instanceof DatabaseTreeNode node ? node : null;
}
- public void previewTable(String qualifiedTableName) {
- PreviewTableSettingsDialog settingsDialog =
- new PreviewTableSettingsDialog(shell, 100, variables, false);
- PreviewTableSettingsDialog.Settings settings = settingsDialog.open();
- if (settings == null) {
- return;
- }
- int limit = settings.rowLimit;
- int queryTimeoutSeconds = settings.queryTimeoutSeconds;
-
- String[] tableNameParts = qualifiedTableName.split("\\.");
-
- GetPreviewTableProgressDialog pd = null;
- if (schemaName == null && tableNameParts.length == 2) {
- // Table name contains both schema name and table name concatenated
- pd =
- new GetPreviewTableProgressDialog(
- shell,
- variables,
- dbMeta,
- tableNameParts[0],
- tableNameParts[1],
- limit,
- queryTimeoutSeconds);
- } else {
- pd =
- new GetPreviewTableProgressDialog(
- shell, variables, dbMeta, null, qualifiedTableName, limit,
queryTimeoutSeconds);
+ @GuiToolbarElement(
+ root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
+ id = TOOLBAR_ITEM_PREVIEW,
+ type = GuiToolbarElementType.BUTTON,
+ toolTip = "i18n::DatabaseExplorerDialog.Toolbar.Preview.Tooltip",
+ image = "ui/images/preview.svg",
+ separator = true)
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_PREVIEW_100,
+ label = "i18n::DatabaseExplorerDialog.Menu.Preview100",
+ image = "ui/images/preview.svg")
+ @GuiKeyboardShortcut(key = SWT.F4)
+ @GuiOsxKeyboardShortcut(key = SWT.F4)
+ public void showTablePreview100() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ showTablePreview(node, false);
+ }
+ }
+
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_PREVIEW_N,
+ label = "i18n::DatabaseExplorerDialog.Menu.PreviewN",
+ image = "ui/images/preview.svg")
+ public void showTablePreviewN() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ showTablePreview(node, true);
+ }
+ }
+
+ public void showTablePreview(DatabaseTreeNode node, boolean askSetting) {
+ int limit = 100;
+ int queryTimeoutSeconds = 0;
+
+ if (askSetting) {
+ PreviewTableSettingsDialog settingsDialog =
+ new PreviewTableSettingsDialog(shell, 100, variables, false);
+ PreviewTableSettingsDialog.Settings settings = settingsDialog.open();
+ if (settings == null) {
+ return;
+ }
+ limit = settings.rowLimit;
+ queryTimeoutSeconds = settings.queryTimeoutSeconds;
}
- List<Object[]> rows = pd.open();
- if (pd.isPreviewSucceeded()) {
+ GetPreviewTableProgressDialog dialog =
+ new GetPreviewTableProgressDialog(
+ shell,
+ variables,
+ databaseMeta,
+ node.getSchemaName(),
+ node.getObjectName(),
+ limit,
+ queryTimeoutSeconds);
+ List<Object[]> rows = dialog.open();
+ if (dialog.isPreviewSucceeded()) {
if (!rows.isEmpty()) {
new ShowRowsDialog(
shell,
variables,
BaseMessages.getString(PKG,
"DatabaseExplorerDialog.ShowRows.Title"),
BaseMessages.getString(
- PKG, "DatabaseExplorerDialog.ShowRows.Message",
qualifiedTableName),
- pd.getRowMeta(),
+ PKG, "DatabaseExplorerDialog.ShowRows.Message",
node.getObjectName()),
+ dialog.getRowMeta(),
rows)
.open();
} else {
@@ -862,103 +740,133 @@ public class DatabaseExplorerDialog extends Dialog {
}
}
- public void showTable(String qualifiedTableName) {
- String sql = dbMeta.getSqlQueryFields(qualifiedTableName);
- IRowMeta result = null;
- try (Database db = new Database(HopGui.getInstance().getLoggingObject(),
variables, dbMeta)) {
- db.connect();
- result = db.getQueryFields(sql, false);
- } catch (Exception e) {
- // Do Nothing
- }
- if (result != null) {
- TransformFieldsDialog sfd =
- new TransformFieldsDialog(shell, variables, SWT.NONE,
qualifiedTableName, result);
- sfd.open();
+ @GuiToolbarElement(
+ root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
+ id = TOOLBAR_ITEM_SHOW_LAYOUT,
+ type = GuiToolbarElementType.BUTTON,
+ toolTip = "i18n::DatabaseExplorerDialog.Toolbar.ShowLayout.Tooltip",
+ image = "ui/images/layout.svg")
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_SHOW_LAYOUT,
+ label = "i18n::DatabaseExplorerDialog.Menu.ShowLayout",
+ image = "ui/images/layout.svg",
+ separator = true)
+ public void showTableLayout() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ String table =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
+ String sql = databaseMeta.getSqlQueryFields(table);
+ IRowMeta result = null;
+ try (Database db =
+ new Database(HopGui.getInstance().getLoggingObject(), variables,
databaseMeta)) {
+ db.connect();
+ result = db.getQueryFields(sql, false);
+ } catch (Exception e) {
+ // Do Nothing
+ }
+ if (result != null) {
+ TransformFieldsDialog sfd =
+ new TransformFieldsDialog(shell, variables, SWT.NONE, table,
result);
+ sfd.open();
+ }
}
}
- public void showCount(String qualifiedTableName) {
- String realTableName =
- (qualifiedTableName.contains(".")
- ? qualifiedTableName.substring(qualifiedTableName.indexOf(".") + 1)
- : qualifiedTableName);
- GetTableSizeProgressDialog pd =
- new GetTableSizeProgressDialog(shell, variables, dbMeta,
realTableName);
- Long size = pd.open();
- if (size != null) {
- MessageBox mb = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
- mb.setMessage(
- BaseMessages.getString(
- PKG,
- "DatabaseExplorerDialog.TableSize.Message",
- qualifiedTableName,
- size.toString()));
- mb.setText(BaseMessages.getString(PKG,
"DatabaseExplorerDialog.TableSize.Title"));
- mb.open();
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_SHOW_SIZE,
+ label = "i18n::DatabaseExplorerDialog.Menu.ShowSize")
+ public void showTableSize() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ GetTableSizeProgressDialog dialog =
+ new GetTableSizeProgressDialog(
+ shell, variables, databaseMeta, node.getObjectName(),
node.getSchemaName());
+ Long size = dialog.open();
+ if (size != null) {
+ String tableName =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
+
+ MessageBox mb = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
+ mb.setMessage(
+ BaseMessages.getString(
+ PKG, "DatabaseExplorerDialog.TableSize.Message", tableName,
size.toString()));
+ mb.setText(BaseMessages.getString(PKG,
"DatabaseExplorerDialog.TableSize.Title"));
+ mb.open();
+ }
}
}
- public void getDDL(String qualifiedTableName) {
- try (Database db = new Database(loggingObject, variables, dbMeta)) {
- db.connect();
- IRowMeta r = db.getTableFields(qualifiedTableName);
- String realTableName =
- (qualifiedTableName.contains(".")
- ? qualifiedTableName.substring(qualifiedTableName.indexOf(".") +
1)
- : qualifiedTableName);
-
- String sql = db.getCreateTableStatement(realTableName, r, null, false,
null, true);
- DatabaseWorkbenchDialog.openSql(dbMeta, sql);
- } catch (HopDatabaseException dbe) {
- new ErrorDialog(
- shell,
- BaseMessages.getString(PKG, "Dialog.Error.Header"),
- BaseMessages.getString(PKG,
"DatabaseExplorerDialog.Error.RetrieveLayout"),
- dbe);
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_DDL,
+ label = "i18n::DatabaseExplorerDialog.Menu.GenDDL")
+ public void showDDL() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ String table =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
+
+ try (Database db = new Database(loggingObject, variables, databaseMeta))
{
+ db.connect();
+ IRowMeta rowMeta = db.getTableFields(table);
+ String sql = db.getCreateTableStatement(table, rowMeta, null, false,
null, true);
+ openSqlEditor(sql);
+ } catch (HopDatabaseException dbe) {
+ new ErrorDialog(
+ shell,
+ BaseMessages.getString(PKG, "Dialog.Error.Header"),
+ BaseMessages.getString(PKG,
"DatabaseExplorerDialog.Error.RetrieveLayout"),
+ dbe);
+ }
}
}
- public void getDDLForOther(String qualifiedTableName) {
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_DDL_OTHER,
+ label = "i18n::DatabaseExplorerDialog.Menu.GenDDLOtherConn")
+ public void showDDLForOther() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null && databases != null) {
+ String table =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
- if (databases != null) {
- try (Database database = new Database(loggingObject, variables, dbMeta))
{
+ try (Database database = new Database(loggingObject, variables,
databaseMeta)) {
database.connect();
- String realTableName =
- (qualifiedTableName.contains(".")
- ? qualifiedTableName.substring(qualifiedTableName.indexOf(".")
+ 1)
- : qualifiedTableName);
- IRowMeta rowMeta = database.getTableFields(realTableName);
+ IRowMeta rowMeta = database.getTableFields(table);
// Now select the other connection...
-
- // Only take non-SAP ERP connections....
- List<DatabaseMeta> databaseMetaList = new ArrayList<>();
- for (DatabaseMeta databaseMeta : databases) {
- databaseMetaList.add(databaseMeta);
- }
-
- String[] connectionNames = new String[databaseMetaList.size()];
+ String[] connectionNames = new String[databases.size()];
for (int i = 0; i < connectionNames.length; i++) {
- connectionNames[i] = (databaseMetaList.get(i)).getName();
+ connectionNames[i] = (databases.get(i)).getName();
}
- EnterSelectionDialog enterSelectionDialog =
+ EnterSelectionDialog dialog =
new EnterSelectionDialog(
shell,
connectionNames,
BaseMessages.getString(PKG,
"DatabaseExplorerDialog.TargetDatabase.Title"),
BaseMessages.getString(PKG,
"DatabaseExplorerDialog.TargetDatabase.Message"));
- String target = enterSelectionDialog.open();
+ String target = dialog.open();
if (target != null) {
- DatabaseMeta targetDatabaseMeta =
DatabaseMeta.findDatabase(databaseMetaList, target);
+ DatabaseMeta targetDatabaseMeta =
DatabaseMeta.findDatabase(databases, target);
try (Database targetDatabase =
new Database(loggingObject, variables, targetDatabaseMeta)) {
String sql =
- targetDatabase.getCreateTableStatement(
- qualifiedTableName, rowMeta, null, false, null, true);
- DatabaseWorkbenchDialog.openSql(targetDatabaseMeta, sql);
+ targetDatabase.getCreateTableStatement(table, rowMeta, null,
false, null, true);
+ openSqlEditor(sql);
}
}
} catch (HopDatabaseException dbe) {
@@ -977,20 +885,51 @@ public class DatabaseExplorerDialog extends Dialog {
}
}
- public void getSql(String qualifiedTableName) {
- String realTableName =
- (qualifiedTableName.contains(".")
- ? qualifiedTableName.substring(qualifiedTableName.indexOf(".") + 1)
- : qualifiedTableName);
- DatabaseWorkbenchDialog.openSql(dbMeta, "SELECT * FROM " + realTableName);
- }
-
- public void getTruncate(String truncateTableReference) {
- DatabaseWorkbenchDialog.openSql(dbMeta, "-- TRUNCATE TABLE " +
truncateTableReference);
+ @GuiToolbarElement(
+ root = GUI_PLUGIN_TOOLBAR_PARENT_ID,
+ id = TOOLBAR_ITEM_SQL_SELECT,
+ type = GuiToolbarElementType.BUTTON,
+ toolTip = "i18n::DatabaseExplorerDialog.Toolbar.SQLSelect.Tooltip",
+ image = "ui/images/script.svg")
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_SQL_SELECT,
+ label = "i18n::DatabaseExplorerDialog.Menu.SQLSelect",
+ image = "ui/images/script.svg",
+ separator = true)
+ public void showSqlSelect() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ String table =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
+ openSqlEditor("SELECT * FROM " + table);
+ }
+ }
+
+ @GuiMenuElement(
+ root = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ parentId = GUI_PLUGIN_CONTEXT_MENU_PARENT_ID,
+ id = CONTEXT_MENU_SQL_TRUNCATE,
+ label = "i18n::DatabaseExplorerDialog.Menu.Truncate")
+ public void showSqlTruncate() {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node != null) {
+ String table =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
+ openSqlEditor("-- TRUNCATE TABLE " + table);
+ }
+ }
+
+ protected void openSqlEditor(String sql) {
+ SqlEditor dialog = new SqlEditor(shell, SWT.NONE, variables, databaseMeta,
dbCache, sql);
+ dialog.open();
}
public void dispose() {
- props.setScreen(new WindowProperty(shell));
+ PropsUi.getInstance().setScreen(new WindowProperty(shell));
shell.dispose();
}
@@ -999,181 +938,56 @@ public class DatabaseExplorerDialog extends Dialog {
dispose();
return;
}
- TreeItem[] selection = wTree.getSelection();
- if (selection.length != 1) {
- return;
- }
- TreeItem selected = selection[0];
- if (completeOkFromThreePartPath(selected)) {
- return;
- }
- completeOkFromFourPartPath(selected);
- }
-
- private boolean completeOkFromThreePartPath(TreeItem selected) {
- String[] path = ConstUi.getTreeStrings(selected);
- if (path.length != 3 || !isTablesViewsOrSynonymsPathSegment(path[1])) {
- return false;
- }
- applyOkSelectionForFlatTableFolder(selected.getText());
- dispose();
- return true;
- }
-
- private void applyOkSelectionForFlatTableFolder(String selectedItemText) {
- schemaName = null;
- tableName = selectedItemText;
- String[] st = tableName.split("\\.", 2);
- if (st.length > 1) {
- schemaName = st[0];
- tableName = st[1];
- }
- }
- private void completeOkFromFourPartPath(TreeItem selected) {
- String[] path = ConstUi.getTreeStrings(selected);
- if (path.length != 4 || !isCatalogOrSchemasPathSegment(path[1])) {
+ DatabaseTreeNode node = getSelectedNode();
+ if (node == null || !node.isTableLike()) {
return;
}
+
if (splitSchemaAndTable) {
- schemaName = path[2];
- tableName = path[3];
+ selectedSchemaName = node.getSchemaName();
+ selectedTableName = node.getObjectName();
} else {
- if (dbMeta == null) {
- return;
- }
- schemaName = null;
- tableName = dbMeta.getQuotedSchemaTableCombination(variables, path[2],
path[3]);
- }
- dispose();
- }
-
- private static boolean isTablesViewsOrSynonymsPathSegment(String
pathSegment) {
- return STRING_TABLES.equalsIgnoreCase(pathSegment)
- || STRING_VIEWS.equalsIgnoreCase(pathSegment)
- || STRING_SYNONYMS.equalsIgnoreCase(pathSegment);
- }
-
- private static boolean isCatalogOrSchemasPathSegment(String pathSegment) {
- return STRING_SCHEMAS.equals(pathSegment) ||
STRING_CATALOG.equals(pathSegment);
- }
-
- public void openSchema(Event e) {
- TreeItem sel = (TreeItem) e.item;
- if (sel == null) {
- return;
+ selectedSchemaName = null;
+ selectedTableName =
+ databaseMeta.getQuotedSchemaTableCombination(
+ variables, node.getSchemaName(), node.getObjectName());
}
- TreeItem up1 = sel.getParentItem();
- if (up1 != null) {
- TreeItem up2 = up1.getParentItem();
- if (up2 != null) {
- TreeItem up3 = up2.getParentItem();
- if (up3 != null) {
- tableName = sel.getText();
- if (!justLook) {
- ok();
- } else {
- previewTable(tableName);
- }
- }
- }
- }
+ dispose();
}
- private void handleTreeMouseDown(Event e) {
- if (e.button == 3) {
- setTreeMenu();
- return;
- }
- if (e.button != 1) {
- return;
- }
-
- TreeItem item = wTree.getItem(new Point(e.x, e.y));
- if (item == null) {
- // Expander ">" is often outside getItem()'s hit box; resolve the row by
Y.
- item = findTreeItemAtY(e.y);
- }
- if (item == null || item.getItemCount() == 0) {
- return;
- }
-
- Rectangle textBounds = item.getBounds(0);
- Rectangle imageBounds = item.getImageBounds(0);
- boolean inGutter = e.x < textBounds.x;
- boolean onImage =
- imageBounds != null && !imageBounds.isEmpty() &&
imageBounds.contains(e.x, e.y);
- if (!inGutter && !onImage) {
+ public void openTreeItem(Event e) {
+ TreeItem[] selection = wTree.getSelection();
+ if (selection == null || selection.length == 0) {
return;
}
+ TreeItem item = selection[0];
- if (onImage) {
- // Folder icon is outside the native expander hit target.
+ DatabaseTreeNode node = (DatabaseTreeNode) item.getData();
+ if (!node.isTableLike()) {
+ // Expand/Collapse hierarchy
item.setExpanded(!item.getExpanded());
return;
}
- // Gutter / ">": native may or may not handle the click (works at 100%,
often misses at
- // high DPI). Wait one display turn; only complement when Expand/Collapse
did not fire
- // around this click — avoids the expand-then-collapse race at 100%.
- final TreeItem target = item;
- final boolean expandedBefore = item.getExpanded();
- final long mouseDownNanos = System.nanoTime();
- wTree
- .getDisplay()
- .asyncExec(
- () -> {
- if (target.isDisposed()) {
- return;
- }
- long delta = lastTreeExpandCollapseNanos - mouseDownNanos;
- // Native handled if Expand/Collapse fired just before or after
MouseDown.
- if (Math.abs(delta) < 100_000_000L) {
- return;
- }
- if (target.getExpanded() != expandedBefore) {
- return;
- }
- target.setExpanded(!expandedBefore);
- });
+ if (justLook) {
+ showTablePreview(node, false);
+ } else {
+ ok();
+ }
}
- private TreeItem findTreeItemAtY(int y) {
- for (TreeItem root : wTree.getItems()) {
- TreeItem found = findTreeItemAtY(root, y);
- if (found != null) {
- return found;
- }
- }
- return null;
+ public void setSelectedSchemaAndTable(String schema, String table) {
+ this.selectedSchemaName = schema;
+ this.selectedTableName = table;
}
- private static TreeItem findTreeItemAtY(TreeItem item, int y) {
- Rectangle textBounds = item.getBounds(0);
- Rectangle imageBounds = item.getImageBounds(0);
- int top = textBounds.y;
- int bottom = textBounds.y + textBounds.height;
- if (imageBounds != null && !imageBounds.isEmpty()) {
- top = Math.min(top, imageBounds.y);
- bottom = Math.max(bottom, imageBounds.y + imageBounds.height);
- }
- if (y >= top && y < bottom) {
- return item;
- }
- if (item.getExpanded()) {
- for (TreeItem child : item.getItems()) {
- TreeItem found = findTreeItemAtY(child, y);
- if (found != null) {
- return found;
- }
- }
- }
- return null;
+ public String getSchemaName() {
+ return selectedSchemaName;
}
- public void setSelectedSchemaAndTable(String schema, String table) {
- this.selectedSchema = schema;
- this.selectedTable = table;
+ public String getTableName() {
+ return selectedTableName;
}
}
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/GetDatabaseInfoProgressDialog.java
b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/GetDatabaseInfoProgressDialog.java
index f60e87d5b6..66cb4137e5 100644
---
a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/GetDatabaseInfoProgressDialog.java
+++
b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/GetDatabaseInfoProgressDialog.java
@@ -40,9 +40,9 @@ import org.eclipse.swt.widgets.Shell;
public class GetDatabaseInfoProgressDialog {
private static final Class<?> PKG = GetDatabaseInfoProgressDialog.class;
- private Shell shell;
+ private final Shell shell;
private final IVariables variables;
- private DatabaseMeta databaseMeta;
+ private final DatabaseMeta databaseMeta;
/**
* Creates a new dialog that will handle the wait while we're finding out
what tables, views etc.
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/SqlEditor.java
b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/SqlEditor.java
index 774e72331e..4d9cf3f9ed 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/database/dialog/SqlEditor.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/database/dialog/SqlEditor.java
@@ -125,15 +125,8 @@ public class SqlEditor {
Button wExec = new Button(shell, SWT.PUSH);
wExec.setText(BaseMessages.getString(PKG, "SQLEditor.Button.Execute"));
- wExec.addListener(
- SWT.Selection,
- e -> {
- try {
- exec();
- } catch (Exception ge) {
- // Ignore errors
- }
- });
+ wExec.addListener(SWT.Selection, e -> exec());
+
Button wClear = new Button(shell, SWT.PUSH);
wClear.setText(BaseMessages.getString(PKG, "SQLEditor.Button.ClearCache"));
wClear.setToolTipText(BaseMessages.getString(PKG,
"SQLEditor.Button.ClearCache.Tooltip"));
@@ -298,47 +291,38 @@ public class SqlEditor {
}
private void exec() {
- DatabaseMeta databaseMeta = connection;
- if (databaseMeta == null) {
- return;
- }
-
- String sqlScript =
- Utils.isEmpty(wScript.getSelectionText()) ? wScript.getText() :
wScript.getSelectionText();
- StringBuilder message = new StringBuilder();
- ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell);
+ try {
+ DatabaseMeta databaseMeta = connection;
+ if (databaseMeta == null) {
+ return;
+ }
- DatabaseProgressCancelWatcher.startIfDesktop(pmd, activeDb::get,
"Hop-SqlEditor-CancelWatcher");
+ String sqlScript =
+ Utils.isEmpty(wScript.getSelectionText())
+ ? wScript.getText()
+ : wScript.getSelectionText();
- try {
- pmd.run(true, monitor -> runSqlScriptWithMonitor(monitor, databaseMeta,
sqlScript, message));
+ ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell);
+ DatabaseProgressCancelWatcher.startIfDesktop(
+ pmd, activeDb::get, "Hop-SqlEditor-CancelWatcher");
+ pmd.run(true, monitor -> runSqlScriptWithMonitor(monitor, databaseMeta,
sqlScript));
} catch (InterruptedException | InvocationTargetException e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
}
-
- EnterTextDialog dialog =
- new EnterTextDialog(
- shell,
- BaseMessages.getString(PKG, "SQLEditor.Result.Title"),
- BaseMessages.getString(PKG, "SQLEditor.Result.Message"),
- message.toString(),
- true);
- dialog.open();
}
private void runSqlScriptWithMonitor(
- IProgressMonitor monitor,
- DatabaseMeta databaseMeta,
- String sqlScript,
- StringBuilder message) {
+ IProgressMonitor monitor, DatabaseMeta databaseMeta, String sqlScript) {
monitor.beginTask(BaseMessages.getString(PKG,
"SQLEditor.Monitor.Execute"), 100);
String raw =
variables.getVariable(
Const.HOP_QUERY_PREVIEW_TIMEOUT,
EnvUtil.getSystemProperty(Const.HOP_QUERY_PREVIEW_TIMEOUT, "0"));
int timeoutSeconds = Math.max(0, Const.toInt(variables.resolve(raw), 0));
+ StringBuilder message = new StringBuilder();
+
try (Database db = new Database(loggingObject, variables, databaseMeta)) {
activeDb.set(db);
if (timeoutSeconds > 0) {
@@ -348,7 +332,9 @@ public class SqlEditor {
db.connect();
int[] nrStats = {0};
+
runScriptStatementsLoop(db, databaseMeta, sqlScript, message, monitor,
nrStats);
+
message.append(
BaseMessages.getString(PKG, "SQLEditor.Log.StatsExecuted",
Integer.toString(nrStats[0])));
message.append(Const.CR);
@@ -356,8 +342,8 @@ public class SqlEditor {
handleConnectFailure(dbe, message);
} finally {
activeDb.set(null);
- shell.getDisplay().asyncExec(this::refreshExecutionResults);
monitor.done();
+ shell.getDisplay().asyncExec(this::refreshExecutionResults);
}
}
@@ -371,26 +357,55 @@ public class SqlEditor {
List<SqlScriptStatement> statements =
databaseMeta.getIDatabase().getSqlScriptStatements(sqlScript +
Const.CR);
boolean aborted = false;
- for (SqlScriptStatement sql : statements) {
+ boolean isQuery = false;
+ for (SqlScriptStatement statement : statements) {
if (aborted || monitor.isCanceled()) {
break;
}
- if (sql.isQuery()) {
+ if (statement.isQuery()) {
nrStats[0]++;
- executeSelectStatement(db, sql, nrStats[0], message);
+ isQuery = true;
+ executeSelectStatement(db, statement, nrStats[0], message, monitor);
} else {
nrStats[0]++;
- aborted = executeDdlStatement(db, sql, databaseMeta, message);
+ aborted = executeDdlStatement(db, statement, databaseMeta, message);
}
}
+
+ // Close progress monitor before displaying result
+ monitor.done();
+
+ if (!isQuery) {
+ shell
+ .getDisplay()
+ .syncExec(
+ () -> {
+ EnterTextDialog dialog =
+ new EnterTextDialog(
+ shell,
+ BaseMessages.getString(PKG, "SQLEditor.Result.Title"),
+ BaseMessages.getString(PKG,
"SQLEditor.Result.Message"),
+ message.toString(),
+ true);
+ dialog.open();
+ });
+ }
}
private void executeSelectStatement(
- Database db, SqlScriptStatement sql, int statNr, StringBuilder message) {
+ Database db,
+ SqlScriptStatement sql,
+ int statNr,
+ StringBuilder message,
+ IProgressMonitor monitor) {
log.logDetailed("launch SELECT statement: " + Const.CR + sql);
try {
List<Object[]> rows = db.getRows(sql.getStatement(), 1000);
IRowMeta rowMeta = db.getReturnRowMeta();
+
+ // Close progress monitor before displaying result
+ monitor.done();
+
if (!rows.isEmpty()) {
shell
.getDisplay()
@@ -417,6 +432,7 @@ public class SqlEditor {
});
}
} catch (HopDatabaseException dbe) {
+ monitor.done();
handleSelectExecutionFailure(dbe, sql, message);
}
}
diff --git a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
index 6d4af46be6..5e5405b65b 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
@@ -248,6 +248,7 @@ public class GuiResource {
@Getter private Image imageRedo;
@Getter private Image imageRefresh;
@Getter private Image imageRegex;
+ @Getter private Image imageRegexDisabled;
@Getter private Image imageRemoveAll;
@Getter private Image imageRemoveSingle;
@Getter private Image imageRename;
@@ -488,6 +489,7 @@ public class GuiResource {
imageExpandAll.dispose();
imageSearch.dispose();
imageRegex.dispose();
+ imageRegexDisabled.dispose();
imageNew.dispose();
imageEdit.dispose();
imageLocked.dispose();
@@ -801,6 +803,8 @@ public class GuiResource {
imagePrint = loadAsResource(display, "ui/images/print.svg",
ConstUi.SMALL_ICON_SIZE);
imageRefresh = loadAsResource(display, "ui/images/refresh.svg",
ConstUi.SMALL_ICON_SIZE);
imageRegex = loadAsResource(display, "ui/images/regex.svg",
ConstUi.SMALL_ICON_SIZE);
+ imageRegexDisabled =
+ loadAsResource(display, "ui/images/regex-disabled.svg",
ConstUi.SMALL_ICON_SIZE);
imageRemoveAll = loadAsResource(display, "ui/images/remove_all.svg",
ConstUi.SMALL_ICON_SIZE);
imageRemoveSingle =
loadAsResource(display, "ui/images/remove_single.svg",
ConstUi.SMALL_ICON_SIZE);
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTableInfoTab.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTableInfoTab.java
index 90ffb43cdc..3d4365a0ad 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTableInfoTab.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTableInfoTab.java
@@ -40,6 +40,7 @@ import org.apache.hop.core.variables.IVariables;
import org.apache.hop.i18n.BaseMessages;
import org.apache.hop.ui.core.FormDataBuilder;
import org.apache.hop.ui.core.PropsUi;
+import org.apache.hop.ui.core.database.DatabaseTreeNode;
import org.apache.hop.ui.core.dialog.ErrorDialog;
import org.apache.hop.ui.core.gui.GuiResource;
import org.apache.hop.ui.core.widget.ColumnInfo;
diff --git
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
index 0e9f94a03d..aa3c101b89 100644
---
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
+++
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import lombok.Getter;
import org.apache.hop.core.Const;
import org.apache.hop.core.database.Catalog;
import org.apache.hop.core.database.Database;
@@ -44,6 +45,8 @@ import org.apache.hop.ui.core.ConstUi;
import org.apache.hop.ui.core.FormDataBuilder;
import org.apache.hop.ui.core.PropsUi;
import org.apache.hop.ui.core.bus.HopGuiEvents;
+import org.apache.hop.ui.core.database.DatabaseTreeNode;
+import org.apache.hop.ui.core.database.DatabaseTreeUtil;
import org.apache.hop.ui.core.dialog.ErrorDialog;
import org.apache.hop.ui.core.dialog.MessageDialogWithToggle;
import org.apache.hop.ui.core.gui.GuiMenuWidgets;
@@ -116,7 +119,7 @@ public class DatabaseWorkbench extends Composite implements
TabClosable {
private final IDatabaseWorkbenchHost host;
private final Map<String, DatabaseConnectionState> connections = new
LinkedHashMap<>();
- private final List<TabItemHandler> items = new ArrayList<>();
+ @Getter private final List<TabItemHandler> items = new ArrayList<>();
private final SashForm horizontalSash;
private final Composite rightComposite;
@@ -650,7 +653,7 @@ public class DatabaseWorkbench extends Composite implements
TabClosable {
}
}
}
- for (String view : namesForSchema(info.getViewMap(),
schema.getSchemaName())) {
+ for (String view : DatabaseTreeUtil.namesForSchema(info.getViewMap(),
schema.getSchemaName())) {
if (filterMatcher.matches(view)) {
return true;
}
@@ -660,7 +663,7 @@ public class DatabaseWorkbench extends Composite implements
TabClosable {
/**
* Tables, views and synonyms under a schema (or catalog). Views get {@code
view.svg} via {@link
- * DatabaseTreeNode#kindOf}.
+ * DatabaseTreeUtil#kindOf}.
*/
private void addSchemaObjects(
TreeItem parent,
@@ -668,19 +671,19 @@ public class DatabaseWorkbench extends Composite
implements TabClosable {
String schemaName,
String[] items,
DatabaseMetaInformation info) {
- Collection<String> views = namesForSchema(info.getViewMap(), schemaName);
- Collection<String> synonyms = namesForSchema(info.getSynonymMap(),
schemaName);
+ Collection<String> views =
DatabaseTreeUtil.namesForSchema(info.getViewMap(), schemaName);
+ Collection<String> synonyms =
DatabaseTreeUtil.namesForSchema(info.getSynonymMap(), schemaName);
List<String> names = new ArrayList<>();
if (items != null) {
names.addAll(Arrays.asList(items));
}
for (String view : views) {
- if (!DatabaseTreeNode.containsIgnoreCase(names, view)) {
+ if (!DatabaseTreeUtil.containsIgnoreCase(names, view)) {
names.add(view);
}
}
for (String synonym : synonyms) {
- if (!DatabaseTreeNode.containsIgnoreCase(names, synonym)) {
+ if (!DatabaseTreeUtil.containsIgnoreCase(names, synonym)) {
names.add(synonym);
}
}
@@ -689,37 +692,14 @@ public class DatabaseWorkbench extends Composite
implements TabClosable {
if (!matchesFilter(name, schemaName, connectionName)) {
continue;
}
- DatabaseTreeNode.Kind kind = DatabaseTreeNode.kindOf(name, views,
synonyms);
+ DatabaseTreeNode.Kind kind = DatabaseTreeUtil.kindOf(name, views,
synonyms);
TreeItem item = new TreeItem(parent, SWT.NONE);
item.setText(name);
- item.setImage(imageFor(kind));
+ item.setImage(DatabaseTreeUtil.imageFor(kind));
item.setData(DatabaseTreeNode.table(kind, connectionName, schemaName,
name));
}
}
- static Collection<String> namesForSchema(Map<String, Collection<String>>
map, String schemaName) {
- if (map == null || map.isEmpty()) {
- return List.of();
- }
- if (schemaName != null) {
- Collection<String> exact = map.get(schemaName);
- if (exact != null) {
- return exact;
- }
- for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
- if (schemaName.equalsIgnoreCase(entry.getKey()) && entry.getValue() !=
null) {
- return entry.getValue();
- }
- }
- }
- Collection<String> empty = map.get("");
- if (empty != null) {
- return empty;
- }
- Collection<String> missing = map.get(null);
- return missing != null ? missing : List.of();
- }
-
private boolean matchesFilter(String name, String schemaName, String
connectionName) {
if (Utils.isEmpty(filterText)) {
return true;
@@ -764,20 +744,11 @@ public class DatabaseWorkbench extends Composite
implements TabClosable {
}
TreeItem item = new TreeItem(parent, SWT.NONE);
item.setText(name);
- item.setImage(imageFor(kind));
+ item.setImage(DatabaseTreeUtil.imageFor(kind));
item.setData(DatabaseTreeNode.table(kind, connectionName, schemaName,
name));
}
}
- private org.eclipse.swt.graphics.Image imageFor(DatabaseTreeNode.Kind kind) {
- GuiResource resources = GuiResource.getInstance();
- return switch (kind) {
- case VIEW -> resources.getImageView();
- case SYNONYM -> resources.getImageSynonym();
- default -> resources.getImageTable();
- };
- }
-
private DatabaseTreeNode selectedNode() {
TreeItem[] selection = tree.getSelection();
if (selection.length != 1) {
@@ -1489,10 +1460,6 @@ public class DatabaseWorkbench extends Composite
implements TabClosable {
}
}
- public List<TabItemHandler> getItems() {
- return items;
- }
-
public boolean remove(IHopFileTypeHandler handler) {
if (handler == null || !handler.isCloseable()) {
return false;
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_de_DE.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_de_DE.properties
index cdf6ad123b..a63dd82fdc 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_de_DE.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_de_DE.properties
@@ -23,12 +23,12 @@ DatabaseExplorerDialog.Error.GenDDL=Konnte die DDL nicht
erzeugen
DatabaseExplorerDialog.Error.RetrieveLayout=Konnte Tabellenstruktur nicht
ermitteln.
DatabaseExplorerDialog.Menu.GenDDL=DDL erzeugen
DatabaseExplorerDialog.Menu.GenDDLOtherConn=DDL f\u00FCr andere Verbindung
generieren
-DatabaseExplorerDialog.Menu.OpenSQL=SQL-Abfrage auf [{0}] erzeugen
-DatabaseExplorerDialog.Menu.Preview100=&Voransicht der ersten 100 Zeilen von
[{0}]
-DatabaseExplorerDialog.Menu.PreviewN=Voransicht der &ersten ... Zeilen von
[{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Struktur der Tabelle [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=Anzahl der Zeilen in [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Tabelle [{0}] leeren
+DatabaseExplorerDialog.Menu.SQLSelect=SQL-Abfrage auf [{0}] erzeugen
+DatabaseExplorerDialog.Menu.Preview100=&Voransicht der ersten 100 Zeilen
+DatabaseExplorerDialog.Menu.PreviewN=Voransicht der &ersten ... Zeilen
+DatabaseExplorerDialog.Menu.ShowLayout=Struktur der Tabelle
+DatabaseExplorerDialog.Menu.ShowSize=Anzahl der Zeilen
+DatabaseExplorerDialog.Menu.Truncate=Tabelle leeren
DatabaseExplorerDialog.NoConnectionsKnown.Message=Zu diesem Zeitpunkt sind
keine weiteren Verbindungen verf\u00FCgbar, f\u00FCr die die DDL generiert
werden k\u00F6nnte.
DatabaseExplorerDialog.NoConnectionsKnown.Title=Keine Verbindungen bekannt
DatabaseExplorerDialog.NoRows.Message=Die Tabelle enth\u00E4lt keine Zeilen
@@ -42,7 +42,7 @@ DatabaseExplorerDialog.TableSize.Message=Tabelle ''{0}''
enth\u00E4lt {1} Zeilen
DatabaseExplorerDialog.TableSize.Title=Zeilenanzahl
DatabaseExplorerDialog.TargetDatabase.Message=W\u00E4hlen Sie die
Zieldatenbank aus
DatabaseExplorerDialog.TargetDatabase.Title=Zieldatenbank
-DatabaseExplorerDialog.Title=Datenbankexplorer auf Verbindung [{0}]
+DatabaseExplorerDialog.Title=Datenbankexplorer
DatabaseExplorerDialog.Views.Label=Sichten
Dialog.Error.Header=Fehler
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=Es ist ein Problem beim
Abrufen von Informationen aus der Datenbank aufgetreten: {0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_en_US.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_en_US.properties
index 8315c8e5c3..72bbf3d143 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_en_US.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_en_US.properties
@@ -18,22 +18,27 @@
DatabaseExplorerDialog.Catalogs.Label=Catalogs
DatabaseExplorerDialog.Error.GenDDL=Couldn''t generate the DDL
DatabaseExplorerDialog.Error.RetrieveLayout=Couldn''t retrieve the table
layout.
-DatabaseExplorerDialog.Menu.GenDDL=Generate DDL
-DatabaseExplorerDialog.Menu.GenDDLOtherConn=Generate DDL for other connection
-DatabaseExplorerDialog.Menu.OpenSQL=Open SQL for [{0}]
-DatabaseExplorerDialog.Menu.Preview100=&Preview first 100 rows of [{0}]
-DatabaseExplorerDialog.Menu.PreviewN=&Preview first ... rows of [{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Show layout of [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=Number of rows of [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Truncate table [{0}]
+DatabaseExplorerDialog.Menu.GenDDL=Generate DDL...
+DatabaseExplorerDialog.Menu.GenDDLOtherConn=Generate DDL for other
connection...
+DatabaseExplorerDialog.Menu.SQLSelect=Generate SQL Select...
+DatabaseExplorerDialog.Menu.Preview100=&Preview first 100 rows...
+DatabaseExplorerDialog.Menu.PreviewN=&Preview first … rows...
+DatabaseExplorerDialog.Menu.ShowLayout=Show layout...
+DatabaseExplorerDialog.Menu.ShowSize=Number of rows...
+DatabaseExplorerDialog.Menu.Truncate=Truncate table...
+DatabaseExplorerDialog.Toolbar.SQLSelect.Tooltip=Generate SQL Select...
+DatabaseExplorerDialog.Toolbar.Preview.Tooltip=Preview first 100 rows...
+DatabaseExplorerDialog.Toolbar.ShowLayout.Tooltip=Show layout...
DatabaseExplorerDialog.NoConnectionsKnown.Message=At this point no other
connections are available to generate the DDL for.
DatabaseExplorerDialog.NoConnectionsKnown.Title=No connections known
DatabaseExplorerDialog.NoRows.Message=The table contains no rows
DatabaseExplorerDialog.NoRows.Title=No rows
DatabaseExplorerDialog.PreviewTable.Message=Number of lines to preview (0
means all lines)
DatabaseExplorerDialog.PreviewTable.Title=Preview limit
+DatabaseExplorerDialog.RegEx.Tooltip=Use wildcard (regular expressions)
DatabaseExplorerDialog.ShowRows.Title=Table data
DatabaseExplorerDialog.ShowRows.Message=Rows of table {0}
+DatabaseExplorerDialog.Search.Placeholder=Search
PreviewTableSettingsDialog.Error.InvalidNumber=Enter valid whole numbers for
rows and timeout.
PreviewTableSettingsDialog.Error.Title=Invalid input
PreviewTableSettingsDialog.Rows.Hint=0 means no row limit on the query (fetch
all rows).
@@ -48,7 +53,7 @@ DatabaseExplorerDialog.TableSize.Message=Table ''{0}''
contains {1} rows
DatabaseExplorerDialog.TableSize.Title=Number of rows
DatabaseExplorerDialog.TargetDatabase.Message=Select the target database
DatabaseExplorerDialog.TargetDatabase.Title=Target database
-DatabaseExplorerDialog.Title=Database explorer on connection [{0}]
+DatabaseExplorerDialog.Title=Database explorer
DatabaseExplorerDialog.Views.Label=Views
Dialog.Error.Header=Error
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=Problem encountered
getting information from the database\: {0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_AR.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_AR.properties
index 61e7e5edae..c7eb5bce64 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_AR.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_AR.properties
@@ -23,12 +23,12 @@ DatabaseExplorerDialog.Error.GenDDL=No pudo generarse el DDL
DatabaseExplorerDialog.Error.RetrieveLayout=No pudo obtenerse el diagrama de
tablas.
DatabaseExplorerDialog.Menu.GenDDL=Generar DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=Generar DDL para otra conexi\u00F3n
-DatabaseExplorerDialog.Menu.OpenSQL=Abrir SQL para [{0}]
-DatabaseExplorerDialog.Menu.Preview100=&Prever las primeros 100 filas de [{0}]
-DatabaseExplorerDialog.Menu.PreviewN=&Prever primeras ... filas de [{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Mostrar diagrama de [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=N\u00FAmero de filas de [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Truncar tablas [{0}]
+DatabaseExplorerDialog.Menu.SQLSelect=Abrir SQL para [{0}]
+DatabaseExplorerDialog.Menu.Preview100=&Prever las primeros 100 filas
+DatabaseExplorerDialog.Menu.PreviewN=&Prever primeras ... filas
+DatabaseExplorerDialog.Menu.ShowLayout=Mostrar diagrama
+DatabaseExplorerDialog.Menu.ShowSize=N\u00FAmero de filas
+DatabaseExplorerDialog.Menu.Truncate=Truncar tablas
DatabaseExplorerDialog.NoConnectionsKnown.Message=En este momento no hay otras
conexiones disponibles para generar DDL.
DatabaseExplorerDialog.NoConnectionsKnown.Title=No se conocen conexiones
DatabaseExplorerDialog.NoRows.Message=La tabla no contiene filas
@@ -42,7 +42,7 @@ DatabaseExplorerDialog.TableSize.Message=La tabla "{0}"
contiene {1} filas
DatabaseExplorerDialog.TableSize.Title=N\u00FAmero de filas
DatabaseExplorerDialog.TargetDatabase.Message=Seleccionar la base de datos
destino
DatabaseExplorerDialog.TargetDatabase.Title=Base de datos destino
-DatabaseExplorerDialog.Title=Explorador de base de datso en la conexi\u00F3n
[{0}]
+DatabaseExplorerDialog.Title=Explorador de base de datso
DatabaseExplorerDialog.Views.Label=Vistas
Dialog.Error.Header=Error
GetDatabaseInfoProgressDialog.Error.Message=\u00A1Ocurri\u00F3 un error al
obtener informaci\u00F3n de la base de datos\!
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_ES.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_ES.properties
index 3545367eaf..07f73aa353 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_ES.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_es_ES.properties
@@ -21,12 +21,12 @@ DatabaseExplorerDialog.Error.GenDDL=No se ha podido generar
el DDL
DatabaseExplorerDialog.Error.RetrieveLayout=No se ha podido recuperar el
dise\u00F1o de la tabla.
DatabaseExplorerDialog.Menu.GenDDL=Generar DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=Generar DDL para otra conexi\u00F3n
-DatabaseExplorerDialog.Menu.OpenSQL=Abrir SQL para [{0}]
-DatabaseExplorerDialog.Menu.Preview100=&Previsualizar las 100 primeras filas
de [{0}]
-DatabaseExplorerDialog.Menu.PreviewN=&Previsualizar primeras ... filas de [{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Mostrar disposici\u00F3n de [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=N\u00FAmero de filas de [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Truncar tabla [{0}]
+DatabaseExplorerDialog.Menu.SQLSelect=Abrir SQL para [{0}]
+DatabaseExplorerDialog.Menu.Preview100=&Previsualizar las 100 primeras filas
+DatabaseExplorerDialog.Menu.PreviewN=&Previsualizar primeras ... filas
+DatabaseExplorerDialog.Menu.ShowLayout=Mostrar disposici\u00F3n
+DatabaseExplorerDialog.Menu.ShowSize=N\u00FAmero de filas
+DatabaseExplorerDialog.Menu.Truncate=Truncar tabla
DatabaseExplorerDialog.NoConnectionsKnown.Message=En este punto no hay otras
conexiones disponibles para generar el DDL.
DatabaseExplorerDialog.NoConnectionsKnown.Title=Sin conexiones conocidas
DatabaseExplorerDialog.NoRows.Message=La tabla no contiene filas
@@ -40,7 +40,7 @@ DatabaseExplorerDialog.TableSize.Message=La tabla ''{0}''
contiene {1} filas
DatabaseExplorerDialog.TableSize.Title=N\u00FAmero de filas
DatabaseExplorerDialog.TargetDatabase.Message=Seleccione la base de datos de
destino
DatabaseExplorerDialog.TargetDatabase.Title=Base de datos de destino
-DatabaseExplorerDialog.Title=Explorador de base de datos en conexi\u00F3n [{0}]
+DatabaseExplorerDialog.Title=Explorador de base de datos
DatabaseExplorerDialog.Views.Label=Vistas
Dialog.Error.Header=Error
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=Problema al obtener
informaci\u00F3n de la base de datos\: {0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_fr_FR.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_fr_FR.properties
index 2913f289b1..f67c489fca 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_fr_FR.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_fr_FR.properties
@@ -23,12 +23,12 @@ DatabaseExplorerDialog.Error.GenDDL=Impossible de
g\u00E9n\u00E9rer les instruct
DatabaseExplorerDialog.Error.RetrieveLayout=Impossible de r\u00E9cup\u00E9rer
les informations depuis la table.
DatabaseExplorerDialog.Menu.GenDDL=G\u00E9n\u00E9rer instructions DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=G\u00E9n\u00E9rer instructions DDL
pour autre connexion
-DatabaseExplorerDialog.Menu.OpenSQL=Ouvrir La fen\u00EAtre ex\u00E9cution SQL
pour [{0}]
-DatabaseExplorerDialog.Menu.Preview100=&Pr\u00E9visualiser les 100
premi\u00E8res lignes de [{0}]
-DatabaseExplorerDialog.Menu.PreviewN=&Pr\u00E9visualiser les ...
premi\u00E8res lignes de [{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Afficher structure sortie de [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=Nombre de lignes de [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Tronquer la table [{0}]
+DatabaseExplorerDialog.Menu.SQLSelect=Ouvrir La fen\u00EAtre ex\u00E9cution SQL
+DatabaseExplorerDialog.Menu.Preview100=&Pr\u00E9visualiser les 100
premi\u00E8res lignes
+DatabaseExplorerDialog.Menu.PreviewN=&Pr\u00E9visualiser les ...
premi\u00E8res lignes
+DatabaseExplorerDialog.Menu.ShowLayout=Afficher structure sortie
+DatabaseExplorerDialog.Menu.ShowSize=Nombre de lignes
+DatabaseExplorerDialog.Menu.Truncate=Tronquer la table
DatabaseExplorerDialog.NoConnectionsKnown.Message=Aucune autre connexion
n''est disponible.
DatabaseExplorerDialog.NoConnectionsKnown.Title=Aucune connexion
DatabaseExplorerDialog.NoRows.Message=La table est vide
@@ -42,7 +42,7 @@ DatabaseExplorerDialog.TableSize.Message=La table ''{0}''
contient {1} ligne(s)
DatabaseExplorerDialog.TableSize.Title=Nombre de lignes
DatabaseExplorerDialog.TargetDatabase.Message=S\u00E9lectionner la base de
donn\u00E9es cible\:
DatabaseExplorerDialog.TargetDatabase.Title=Base de donn\u00E9es cible
-DatabaseExplorerDialog.Title=Explorateur base de donn\u00E9es sur la connexion
[{0}]
+DatabaseExplorerDialog.Title=Explorateur base de donn\u00E9es
DatabaseExplorerDialog.Views.Label=Vues
Dialog.Error.Header=Erreur
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=Apache Hop a
rencontr\u00E9 une erreur lors de la tentative de r\u00E9cup\u00E9ration des
informations depuis la base de donn\u00E9es\: {0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_it_IT.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_it_IT.properties
index c1aa7b6e9e..389e9ddfc2 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_it_IT.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_it_IT.properties
@@ -20,12 +20,12 @@ DatabaseExplorerDialog.Error.GenDDL=Impossibile generare il
DDL
DatabaseExplorerDialog.Error.RetrieveLayout=Impossibile recuperare il layout
della tabella.
DatabaseExplorerDialog.Menu.GenDDL=Genera DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=Genera DDL per altra connessione
-DatabaseExplorerDialog.Menu.OpenSQL=Apri SQL per [{0}]
-DatabaseExplorerDialog.Menu.Preview100=&Anteprima delle prime 100 righe di
[{0}]
-DatabaseExplorerDialog.Menu.PreviewN=&Anteprima delle prime ... righe di [{0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Mostra layout di [{0}]
-DatabaseExplorerDialog.Menu.ShowSize=Numero di righe di [{0}]
-DatabaseExplorerDialog.Menu.Truncate=Tronca tabella [{0}]
+DatabaseExplorerDialog.Menu.SQLSelect=Apri SQL per [{0}]
+DatabaseExplorerDialog.Menu.Preview100=&Anteprima delle prime 100 righe
+DatabaseExplorerDialog.Menu.PreviewN=&Anteprima delle prime ... righe
+DatabaseExplorerDialog.Menu.ShowLayout=Mostra layout
+DatabaseExplorerDialog.Menu.ShowSize=Numero di righe
+DatabaseExplorerDialog.Menu.Truncate=Tronca tabella
DatabaseExplorerDialog.NoConnectionsKnown.Message=A questo punto nessuna
connessione \u00E8 disponibile per generare DDL.
DatabaseExplorerDialog.NoConnectionsKnown.Title=Nessuna connessione conosciuta
DatabaseExplorerDialog.NoRows.Message=La tabella non contiene righe
@@ -39,7 +39,7 @@ DatabaseExplorerDialog.TableSize.Message=La tabella ''{0}''
contiene {1} righe
DatabaseExplorerDialog.TableSize.Title=Numero di righe
DatabaseExplorerDialog.TargetDatabase.Message=Seleziona il database di
destinazione\:
DatabaseExplorerDialog.TargetDatabase.Title=Database di destinazione
-DatabaseExplorerDialog.Title=Database explorer per la connessione [{0}]
+DatabaseExplorerDialog.Title=Database explorer
DatabaseExplorerDialog.Views.Label=Viste
Dialog.Error.Header=Errore
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=E'' stato rilevato un
problema nel recuperare le informazioni dal database\: {0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ja_JP.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ja_JP.properties
index dbc5e00cb7..5899374409 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ja_JP.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ja_JP.properties
@@ -23,7 +23,7 @@
DatabaseExplorerDialog.Error.GenDDL=DDL\u3092\u751F\u6210\u3067\u304D\u307E\u305
DatabaseExplorerDialog.Error.RetrieveLayout=\u30C6\u30FC\u30D6\u30EB\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u8AAD\u307F\u51FA\u305B\u307E\u305B\u3093\u3067\u3057\u305F\u3002
DatabaseExplorerDialog.Menu.GenDDL=Generate DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=\u4ED6\u306E\u63A5\u7D9A\u306EDDL\u751F\u6210
-DatabaseExplorerDialog.Menu.OpenSQL=[{0}] \u306ESQL\u3092\u958B\u304F
+DatabaseExplorerDialog.Menu.SQLSelect=[{0}] \u306ESQL\u3092\u958B\u304F
DatabaseExplorerDialog.Menu.Preview100=[{0}]
\u306E\u6700\u521D\u306E100\u884C\u3092\u30D7\u30EC\u30D3\u30E5\u30FC(&P)
DatabaseExplorerDialog.Menu.PreviewN=[{0}] \u306E\u6700\u521D\u306E ...
\u884C\u3092\u30D7\u30EC\u30D3\u30E5\u30FC(&P)
DatabaseExplorerDialog.Menu.ShowLayout=[{0}]
\u306E\u30EC\u30A4\u30A2\u30A6\u30C8\u3092\u8868\u793A
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ko_KR.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ko_KR.properties
index 6dee1a3825..5450b05bee 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ko_KR.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_ko_KR.properties
@@ -23,7 +23,7 @@ DatabaseExplorerDialog.Error.GenDDL=DDL\uC744
\uC0DD\uC131\uD560 \uC218 \uC5C6\u
DatabaseExplorerDialog.Error.RetrieveLayout=\uD14C\uC774\uBE14
\uB808\uC774\uC544\uC6C3\uC744 \uAC00\uC838\uC62C \uC218
\uC5C6\uC2B5\uB2C8\uB2E4.
DatabaseExplorerDialog.Menu.GenDDL=DDL \uC0DD\uC131
DatabaseExplorerDialog.Menu.GenDDLOtherConn=\uB2E4\uB978 \uC5F0\uACB0\uC758
DDL \uC0DD\uC131
-DatabaseExplorerDialog.Menu.OpenSQL=[{0}] \uC758 SQL \uC5F4\uAE30
+DatabaseExplorerDialog.Menu.SQLSelect=[{0}] \uC758 SQL \uC5F4\uAE30
DatabaseExplorerDialog.Menu.Preview100=[{0}]\uC758 \uCC98\uC74C 100
\uB85C\uC6B0 \uBBF8\uB9AC\uBCF4\uAE30
DatabaseExplorerDialog.Menu.PreviewN=[{0}] \uC758 \uCC98\uC74C ...
\uB85C\uC6B0 \uBBF8\uB9AC\uBCF4\uAE30(&P)
DatabaseExplorerDialog.Menu.ShowLayout=[{0}]\uC758 \uB808\uC774\uC544\uC6C3
\uBCF4\uAE30
@@ -42,7 +42,7 @@ DatabaseExplorerDialog.TableSize.Message=\uD14C\uC774\uBE14
''{0}'' \uB294 {1} \
DatabaseExplorerDialog.TableSize.Title=\uB85C\uC6B0 \uC218
DatabaseExplorerDialog.TargetDatabase.Message=\uB300\uC0C1
\uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uC120\uD0DD:
DatabaseExplorerDialog.TargetDatabase.Title=\uB300\uC0C1
\uB370\uC774\uD130\uBCA0\uC774\uC2A4
-DatabaseExplorerDialog.Title=[{0}] \uC5F0\uACB0\uC758
\uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uD0D0\uC0C9
+DatabaseExplorerDialog.Title=\uC5F0\uACB0\uC758
\uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uD0D0\uC0C9
DatabaseExplorerDialog.Views.Label=\uBDF0
Dialog.Error.Header=\uC624\uB958
GetDatabaseInfoProgressDialog.Error.GettingInfoTable=\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0\uC11C
\uC815\uBCF4\uB97C \uAC00\uC838\uC624\uB294 \uC911 \uBB38\uC81C \uBC1C\uC0DD:
{0}
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_pt_BR.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_pt_BR.properties
index eaef50a596..4baf2fcea0 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_pt_BR.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_pt_BR.properties
@@ -53,10 +53,10 @@ SQLEditor.Position.Label=Linha {0} Coluna {1}
DatabaseExplorerDialog.Error.GenDDL=Não consegui gerar o DDL.
DatabaseExplorerDialog.Error.RetrieveLayout=Não consegui recuperar o layout da
tabela.
DatabaseExplorerDialog.Menu.GenDDLOtherConn=Gere DDL para outra conexão.
-DatabaseExplorerDialog.Menu.OpenSQL=Abrir SQL para [{0}]
-DatabaseExplorerDialog.Menu.Preview100=Antever as primeiras 100 fileiras de
-DatabaseExplorerDialog.Menu.PreviewN=&Preview first ... linhas de [ {0}]
-DatabaseExplorerDialog.Menu.ShowLayout=Mostrar layout de [ {0}]
+DatabaseExplorerDialog.Menu.SQLSelect=Abrir SQL
+DatabaseExplorerDialog.Menu.Preview100=Antever as primeiras 100 fileiras
+DatabaseExplorerDialog.Menu.PreviewN=&Preview first ... linhas
+DatabaseExplorerDialog.Menu.ShowLayout=Mostrar layout
DatabaseExplorerDialog.NoConnectionsKnown.Message=Neste ponto, nenhuma outra
conexão está disponível para gerar o DDL.
DatabaseExplorerDialog.PreviewTable.Message=Número de linhas para visualização
(0 significa todas as linhas)
DatabaseExplorerDialog.TargetDatabase.Message=Selecione o banco de dados alvo
diff --git
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_zh_CN.properties
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_zh_CN.properties
index f825ace114..a7986ec9af 100644
---
a/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_zh_CN.properties
+++
b/ui/src/main/resources/org/apache/hop/ui/core/database/dialog/messages/messages_zh_CN.properties
@@ -22,7 +22,7 @@ DatabaseExplorerDialog.Error.GenDDL=\u4E0D\u80FD\u751F\u6210
DDL \u8BED\u53E5
DatabaseExplorerDialog.Error.RetrieveLayout=\u4E0D\u80FD\u62BD\u53D6\u8868\u7ED3\u6784
DatabaseExplorerDialog.Menu.GenDDL=\u751F\u6210 DDL
DatabaseExplorerDialog.Menu.GenDDLOtherConn=\u4E3A\u5176\u5B83\u8FDE\u63A5\u751F\u6210
DDL
-DatabaseExplorerDialog.Menu.OpenSQL=\u6253\u5F00 {{0}} \u4E0A\u7684 SQL
+DatabaseExplorerDialog.Menu.SQLSelect=\u6253\u5F00 {{0}} \u4E0A\u7684 SQL
DatabaseExplorerDialog.Menu.Preview100=\u9884\u89C8 [{0}] \u7684\u524D 100
\u884C(&P)
DatabaseExplorerDialog.Menu.PreviewN=\u9884\u89C8 [{0}] \u7684\u524D ...
\u884C(&P)
DatabaseExplorerDialog.Menu.ShowLayout=\u67E5\u770B [{0}]
\u7684\u8868\u7ED3\u6784
diff --git a/ui/src/main/resources/ui/images/layout.svg
b/ui/src/main/resources/ui/images/layout.svg
new file mode 100644
index 0000000000..6eb3d76211
--- /dev/null
+++ b/ui/src/main/resources/ui/images/layout.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24
24">
+ <path fill="none" stroke="#0F3B5A" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2" d="M3 4a1 1 0 0 1 1-1h16a1 1 0 0 1 1
1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zm6-1v18m6-18v18"/>
+</svg>
\ No newline at end of file
diff --git a/ui/src/main/resources/ui/images/regex-disabled.svg
b/ui/src/main/resources/ui/images/regex-disabled.svg
new file mode 100644
index 0000000000..10bad68b5f
--- /dev/null
+++ b/ui/src/main/resources/ui/images/regex-disabled.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <path fill="#D7D7D7" d="M16,16.92C15.67,16.97 15.34,17 15,17C14.66,17
14.33,16.97 14,16.92V13.41L11.5,15.89C11,15.5 10.5,15
10.11,14.5L12.59,12H9.08C9.03,11.67 9,11.34 9,11C9,10.66 9.03,10.33
9.08,10H12.59L10.11,7.5C10.3,7.25 10.5,7 10.76,6.76V6.76C11,6.5 11.25,6.3
11.5,6.11L14,8.59V5.08C14.33,5.03 14.66,5 15,5C15.34,5 15.67,5.03
16,5.08V8.59L18.5,6.11C19,6.5 19.5,7 19.89,7.5L17.41,10H20.92C20.97,10.33
21,10.66 21,11C21,11.34 20.97,11.67 20.92,12H17.41L19.89,14.5C19.7,14.75
19.5,15 1 [...]
+</svg>
\ No newline at end of file
diff --git a/ui/src/main/resources/ui/images/regex.svg
b/ui/src/main/resources/ui/images/regex.svg
index 85e589eb0e..469cf27c7c 100644
--- a/ui/src/main/resources/ui/images/regex.svg
+++ b/ui/src/main/resources/ui/images/regex.svg
@@ -1,20 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
- <g>
- <g>
- <rect fill="none" width="16" height="16"/>
- </g>
- </g>
- <g>
- <g>
- <polygon fill="#0E3A5A" stroke="#0E3A5A" stroke-miterlimit="10"
points="1.9,1.5 4,1.5 4,0.5 0.6,0.5 0.6,15.5 4,15.5 4,14.5
- 1.9,14.5 "/>
- <polygon fill="#0E3A5A" stroke="#0E3A5A" stroke-miterlimit="10"
points="12,0.5 12,1.5 14.1,1.5 14.1,14.5 12,14.5 12,15.5
- 15.4,15.5 15.4,0.5 "/>
- <polygon fill="#0E3A5A" stroke="#0E3A5A" stroke-width="0.25"
stroke-miterlimit="10" points="3.4,3.5 8.7,12.8 9.6,12.8 4.2,3.5
- "/>
- <polygon fill="#0E3A5A" points="10.7,6 12.6,6.2 12.6,5.3 10.7,5.6
10.7,5.6 11.9,4 11.2,3.5 10.4,5.3 10.3,5.3 9.5,3.5 8.8,4
- 10,5.6 10,5.6 8.1,5.3 8.1,6.2 10,6 10,6 8.8,7.6 9.5,8
10.3,6.2 10.4,6.2 11.1,8 11.9,7.5 10.7,6 "/>
- </g>
- </g>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+ <path fill="#0F3B5A" d="M16,16.92C15.67,16.97 15.34,17 15,17C14.66,17
14.33,16.97 14,16.92V13.41L11.5,15.89C11,15.5 10.5,15
10.11,14.5L12.59,12H9.08C9.03,11.67 9,11.34 9,11C9,10.66 9.03,10.33
9.08,10H12.59L10.11,7.5C10.3,7.25 10.5,7 10.76,6.76V6.76C11,6.5 11.25,6.3
11.5,6.11L14,8.59V5.08C14.33,5.03 14.66,5 15,5C15.34,5 15.67,5.03
16,5.08V8.59L18.5,6.11C19,6.5 19.5,7 19.89,7.5L17.41,10H20.92C20.97,10.33
21,10.66 21,11C21,11.34 20.97,11.67 20.92,12H17.41L19.89,14.5C19.7,14.75
19.5,15 1 [...]
+</svg>
\ No newline at end of file
diff --git a/ui/src/main/resources/ui/images/run-all.svg
b/ui/src/main/resources/ui/images/run-all.svg
index 076840be38..1839ad3d78 100644
--- a/ui/src/main/resources/ui/images/run-all.svg
+++ b/ui/src/main/resources/ui/images/run-all.svg
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml version="1.0" encoding="UTF-8"?>
<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path fill="#0e3a5a"
d="m 8.8514669,8.6850151 -6.363,3.6919999 c -0.54,0.313
-1.233,-0.066 -1.233,-0.697 V 4.2960151 c 0,-0.63 0.692,-1.01 1.233,-0.696 l
6.363,3.692 a 0.802,0.802 0 0 1 0,1.393 z"
- style="fill:#4da2e3;fill-opacity:.4"/>
+ style="fill:#0e3a5a;fill-opacity:.4"/>
<path fill="#0e3a5a"
d="M 11.553752,8.7145888 5.1907514,12.406589 c -0.54,0.313
-1.233,-0.066 -1.233,-0.697 V 4.3255888 c 0,-0.63 0.692,-1.01 1.233,-0.696 l
6.3630006,3.692 a 0.802,0.802 0 0 1 0,1.393 z"
- style="fill:#1b74b4;fill-opacity:.7"/>
+ style="fill:#0e3a5a;fill-opacity:.7"/>
<path fill="#0e3a5a"
d="M 14.274315,8.6187097 7.9113144,12.31071 c -0.54,0.313
-1.233,-0.066 -1.233,-0.697 V 4.2297097 c 0,-0.63 0.692,-1.01 1.233,-0.696 l
6.3630006,3.692 a 0.802,0.802 0 0 1 0,1.393 z"
- style="fill:#1b74b4;fill-opacity:1"/>
+ style="fill:#0e3a5a;fill-opacity:1"/>
</svg>
diff --git
a/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNodeTest.java
b/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNodeTest.java
index 87ebb25b6b..b97ffb3643 100644
---
a/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNodeTest.java
+++
b/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseTreeNodeTest.java
@@ -24,6 +24,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.apache.hop.ui.core.database.DatabaseTreeNode;
+import org.apache.hop.ui.core.database.DatabaseTreeUtil;
import org.junit.jupiter.api.Test;
class DatabaseTreeNodeTest {
@@ -32,25 +34,25 @@ class DatabaseTreeNodeTest {
void kindOfPrefersViewThenSynonymThenTable() {
assertEquals(
DatabaseTreeNode.Kind.VIEW,
- DatabaseTreeNode.kindOf("orders_v", Set.of("orders_v"), Set.of()));
+ DatabaseTreeUtil.kindOf("orders_v", Set.of("orders_v"), Set.of()));
assertEquals(
DatabaseTreeNode.Kind.VIEW,
- DatabaseTreeNode.kindOf("ORDERS_V", Set.of("orders_v"), Set.of()));
+ DatabaseTreeUtil.kindOf("ORDERS_V", Set.of("orders_v"), Set.of()));
assertEquals(
DatabaseTreeNode.Kind.SYNONYM,
- DatabaseTreeNode.kindOf("orders_s", Set.of(), Set.of("orders_s")));
+ DatabaseTreeUtil.kindOf("orders_s", Set.of(), Set.of("orders_s")));
assertEquals(
DatabaseTreeNode.Kind.TABLE,
- DatabaseTreeNode.kindOf("orders", Set.of("orders_v"), Set.of()));
+ DatabaseTreeUtil.kindOf("orders", Set.of("orders_v"), Set.of()));
}
@Test
void namesForSchemaMatchesIgnoreCaseAndEmptyKeys() {
Map<String, java.util.Collection<String>> map =
Map.of("Public", List.of("v1"), "", List.of("root_view"));
- assertEquals(List.of("v1"), DatabaseWorkbench.namesForSchema(map,
"public"));
- assertEquals(List.of("root_view"), DatabaseWorkbench.namesForSchema(map,
null));
- assertTrue(DatabaseWorkbench.namesForSchema(Map.of(), "public").isEmpty());
+ assertEquals(List.of("v1"), DatabaseTreeUtil.namesForSchema(map,
"public"));
+ assertEquals(List.of("root_view"), DatabaseTreeUtil.namesForSchema(map,
null));
+ assertTrue(DatabaseTreeUtil.namesForSchema(Map.of(), "public").isEmpty());
}
@Test
@@ -64,8 +66,8 @@ class DatabaseTreeNodeTest {
@Test
void containsIgnoreCase() {
- assertTrue(DatabaseTreeNode.containsIgnoreCase(List.of("Alpha"), "alpha"));
- assertFalse(DatabaseTreeNode.containsIgnoreCase(List.of("Alpha"), "beta"));
- assertFalse(DatabaseTreeNode.containsIgnoreCase(null, "alpha"));
+ assertTrue(DatabaseTreeUtil.containsIgnoreCase(List.of("Alpha"), "alpha"));
+ assertFalse(DatabaseTreeUtil.containsIgnoreCase(List.of("Alpha"), "beta"));
+ assertFalse(DatabaseTreeUtil.containsIgnoreCase(null, "alpha"));
}
}