提交 5834591d 编写于 作者: J jurgen

Structured search results

Former-commit-id: 7d069508
上级 c4625d29
Major:
1. Folder for connections
2. Multiple result sets support (MS SQL)
3. Dialect-dependent SQL generator
4. Client-side filters (maybe a bad idea)
5. Outline for data editor (RSV) - columns' filters, search, hide/show
6. Check on MacOS
7. Query manager fixes. + keep only primitive props + persistence
8. Connection per editor support. Host ExecutionContext in editors instead of DataSource.
9. Async autocomplete
1. Multiple result sets support (MS SQL)
2. Dialect-dependent SQL generator
3. Client-side filters (maybe a bad idea)
4. Outline for data editor (RSV) - columns' filters, search, hide/show
5. Check on MacOS
6. Query manager fixes. + keep only primitive props + persistence
7. Connection per editor support. Host ExecutionContext in editors instead of DataSource.
8. Async autocomplete
Show container in search results
Find table/object (similar to eclipse ctrl-shift-r/t)
Minor:
......
......@@ -212,6 +212,7 @@ category.rs.description=Result Set Commands
perspective.name=DBeaver
meta.org.jkiss.dbeaver.model.DBPNamedObject.name.name=Name
meta.org.jkiss.dbeaver.model.data.DBDValueLocator.entity.name=Table
meta.org.jkiss.dbeaver.model.data.DBDValueLocator.uniqueKey.name=Key
meta.org.jkiss.dbeaver.model.impl.jdbc.JDBCDataSource.name.name=Name
......
......@@ -19,6 +19,8 @@
package org.jkiss.dbeaver.model;
import org.jkiss.dbeaver.model.meta.Property;
/**
* Abstract model object
*/
......@@ -30,6 +32,7 @@ public interface DBPNamedObject extends DBPObject
*
* @return object name
*/
@Property(viewable = true, order = 1)
String getName();
}
\ No newline at end of file
......@@ -23,13 +23,7 @@ import org.eclipse.jface.viewers.ITreeContentProvider;
/**
* TreeContentProvider
*/
public class TreeContentProvider extends ListContentProvider implements ITreeContentProvider {
@Override
public Object[] getChildren(Object parentElement)
{
return null;
}
public abstract class TreeContentProvider extends ListContentProvider implements ITreeContentProvider {
@Override
public Object getParent(Object element)
......@@ -37,10 +31,4 @@ public class TreeContentProvider extends ListContentProvider implements ITreeCon
return null;
}
@Override
public boolean hasChildren(Object element)
{
return false;
}
}
......@@ -56,6 +56,7 @@ import org.jkiss.dbeaver.ui.properties.PropertySourceEditable;
import org.jkiss.utils.CommonUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
......@@ -65,22 +66,17 @@ import java.util.Set;
public abstract class NodeListControl extends ObjectListControl<DBNNode> implements IDataSourceProvider, INavigatorModelView, IDBNListener, IMenuListener {
//static final Log log = LogFactory.getLog(NodeListControl.class);
private IWorkbenchSite workbenchSite;
private DBNNode rootNode;
private final IWorkbenchSite workbenchSite;
private final DBNNode rootNode;
private DBXTreeNode nodeMeta;
private NodeSelectionProvider selectionProvider;
private final NodeSelectionProvider selectionProvider;
public NodeListControl(
Composite parent,
int style,
final IWorkbenchSite workbenchSite,
DBNNode rootNode,
DBXTreeNode nodeMeta)
protected NodeListControl(Composite parent, int style, final IWorkbenchSite workbenchSite, DBNNode rootNode, IContentProvider contentProvider)
{
super(parent, style, createContentProvider(rootNode, nodeMeta));
super(parent, style, contentProvider);
this.workbenchSite = workbenchSite;
this.rootNode = rootNode;
this.nodeMeta = nodeMeta;
this.selectionProvider = new NodeSelectionProvider(super.getSelectionProvider());
// Add context menu
......@@ -108,8 +104,17 @@ public abstract class NodeListControl extends ObjectListControl<DBNNode> impleme
NavigatorUtils.addDragAndDropSupport(getItemsViewer());
DBeaverCore.getInstance().getNavigatorModel().addListener(this);
}
//getSelectionProvider().setSelection(new StructuredSelection(rootNode));
public NodeListControl(
Composite parent,
int style,
final IWorkbenchSite workbenchSite,
DBNNode rootNode,
DBXTreeNode nodeMeta)
{
this(parent, style, workbenchSite, rootNode, createContentProvider(rootNode, nodeMeta));
this.nodeMeta = nodeMeta;
}
@Override
......@@ -207,19 +212,17 @@ public abstract class NodeListControl extends ObjectListControl<DBNNode> impleme
}
@Override
protected Class<?>[] getListBaseTypes()
protected Class<?>[] getListBaseTypes(Collection<DBNNode> items)
{
List<Class<?>> baseTypes;
// Collect base types for root node
if (getRootNode() instanceof DBNDatabaseNode) {
if (getRootNode() instanceof DBNDatabaseNode && nodeMeta != null) {
DBNDatabaseNode dbNode = (DBNDatabaseNode) getRootNode();
baseTypes = dbNode.getChildrenTypes(nodeMeta);
List<Class<?>> baseTypes = dbNode.getChildrenTypes(nodeMeta);
// Collect base types for inline children
return CommonUtils.isEmpty(baseTypes) ? null : baseTypes.toArray(new Class<?>[baseTypes.size()]);
} else {
baseTypes = null;
return null;
}
// Collect base types for inline children
return baseTypes == null || baseTypes.isEmpty() ? null : baseTypes.toArray(new Class<?>[baseTypes.size()]);
}
@Override
......@@ -233,7 +236,7 @@ public abstract class NodeListControl extends ObjectListControl<DBNNode> impleme
return rootNode;
}
public DBXTreeNode getNodeMeta()
protected DBXTreeNode getNodeMeta()
{
return nodeMeta;
}
......
......@@ -327,7 +327,7 @@ public abstract class ObjectListControl<OBJECT_TYPE> extends ProgressPageControl
{
// Collect list of items' classes
final List<Class<?>> classList = new ArrayList<Class<?>>();
Class<?>[] baseTypes = getListBaseTypes();
Class<?>[] baseTypes = getListBaseTypes(items);
if (!CommonUtils.isEmpty(baseTypes)) {
Collections.addAll(classList, baseTypes);
}
......@@ -600,10 +600,18 @@ public abstract class ObjectListControl<OBJECT_TYPE> extends ProgressPageControl
for (Class valueClass = objectValue.getClass(); prop == null && valueClass != Object.class; valueClass = valueClass.getSuperclass()) {
prop = column.propMap.get(valueClass);
}
if (prop == null) {
for (Map.Entry<Class<?>, ObjectPropertyDescriptor> entry : column.propMap.entrySet()) {
if (entry.getKey().isInstance(objectValue)) {
prop = entry.getValue();
break;
}
}
}
return prop;
}
protected Class<?>[] getListBaseTypes()
protected Class<?>[] getListBaseTypes(Collection<OBJECT_TYPE> items)
{
return null;
}
......
......@@ -399,7 +399,7 @@ public class ObjectPropertyDescriptor extends ObjectAttributeDescriptor implemen
result = resourceBundle.getString(messageID);
} catch (Exception e) {
// Try to find the same property in parent classes
for (Class parent = getter.getDeclaringClass().getSuperclass(); parent != Object.class; parent = parent.getSuperclass()) {
for (Class parent = getter.getDeclaringClass().getSuperclass(); parent != null && parent != Object.class; parent = parent.getSuperclass()) {
try {
Method parentGetter = parent.getMethod(getter.getName(), getter.getParameterTypes());
Class<?> parentOwner = parentGetter.getDeclaringClass();
......
......@@ -18,9 +18,8 @@
*/
package org.jkiss.dbeaver.ui.search.metadata;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
......@@ -30,17 +29,20 @@ import org.eclipse.ui.part.Page;
import org.jkiss.dbeaver.core.CoreMessages;
import org.jkiss.dbeaver.core.DBeaverCore;
import org.jkiss.dbeaver.ext.ui.INavigatorModelView;
import org.jkiss.dbeaver.model.DBPNamedObject;
import org.jkiss.dbeaver.model.navigator.DBNContainer;
import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.navigator.DBNResource;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.ui.controls.itemlist.ItemListControl;
import org.jkiss.dbeaver.runtime.load.jobs.LoadingJob;
import org.jkiss.dbeaver.ui.controls.TreeContentProvider;
import org.jkiss.dbeaver.ui.controls.itemlist.NodeListControl;
import org.jkiss.dbeaver.ui.search.IObjectSearchResultPage;
import java.util.Collection;
import java.util.*;
public class SearchMetadataResultsPage extends Page implements IObjectSearchResultPage<DBNNode>, INavigatorModelView {
static final Log log = LogFactory.getLog(SearchMetadataResultsPage.class);
private SearchResultsControl itemList;
@Override
......@@ -80,6 +82,7 @@ public class SearchMetadataResultsPage extends Page implements IObjectSearchResu
{
if (itemList != null && !itemList.isDisposed()) {
itemList.appendListData(objects);
((TreeViewer)itemList.getItemsViewer()).expandAll();
}
}
......@@ -101,15 +104,138 @@ public class SearchMetadataResultsPage extends Page implements IObjectSearchResu
return itemList.getNavigatorViewer();
}
private class SearchResultsControl extends ItemListControl {
private class SearchResultsControl extends NodeListControl {
public SearchResultsControl(Composite resultsGroup)
{
super(resultsGroup, SWT.SHEET, getSite(), DBeaverCore.getInstance().getNavigatorModel().getRoot(), null);
super(resultsGroup, SWT.SHEET, getSite(),
DBeaverCore.getInstance().getNavigatorModel().getRoot(),
new ResultsContentProvider());
}
@Override
protected void fillCustomToolbar(ToolBarManager toolbarManager)
{
}
@Override
protected Class<?>[] getListBaseTypes(Collection<DBNNode> items)
{
return new Class<?>[] {DBPNamedObject.class};
}
@Override
protected LoadingJob<Collection<DBNNode>> createLoadService()
{
// No load service
return null;
}
}
private static class ResultsNode {
DBNNode node;
ResultsNode parent;
final List<ResultsNode> children = new ArrayList<ResultsNode>();
public ResultsNode(DBNNode node, ResultsNode parent)
{
this.node = node;
this.parent = parent;
}
DBNNode[] getChildrenNodes()
{
DBNNode[] nodes = new DBNNode[children.size()];
for (int i = 0; i < children.size(); i++) {
nodes[i] = children.get(i).node;
}
return nodes;
}
}
private class ResultsContentProvider extends TreeContentProvider {
private ResultsNode rootResults;
private Map<DBNNode,ResultsNode> nodeMap;
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
if (newInput instanceof Collection) {
rebuildObjectTree((Collection<DBNNode>) newInput);
}
}
@Override
public Object getParent(Object element)
{
if (element instanceof DBNNode) {
ResultsNode results = nodeMap.get(element);
if (results != null && results.parent != null) {
return results.parent.node;
}
}
return null;
}
@Override
public boolean hasChildren(Object parentElement)
{
if (parentElement instanceof DBNNode) {
ResultsNode results = nodeMap.get(parentElement);
return results != null && !results.children.isEmpty();
}
return false;
}
@Override
public Object[] getChildren(Object parentElement)
{
if (parentElement instanceof DBNNode) {
ResultsNode results = nodeMap.get(parentElement);
if (results != null) {
return results.getChildrenNodes();
}
}
return null;
}
@Override
public Object[] getElements(Object inputElement)
{
return rootResults.getChildrenNodes();
}
private void rebuildObjectTree(Collection<DBNNode> nodeList)
{
rootResults = new ResultsNode(getRootNode(), null);
nodeMap = new IdentityHashMap<DBNNode, ResultsNode>();
final List<DBNNode> allParents = new ArrayList<DBNNode>();
for (DBNNode node : nodeList) {
// Collect parent nodes
allParents.clear();
for (DBNNode parent = node.getParentNode(); parent != null && parent != getRootNode(); parent = parent.getParentNode()) {
if (parent instanceof DBNContainer || parent instanceof DBNResource) {
continue;
}
allParents.add(0, parent);
}
// Construct hierarchy
ResultsNode curParentResults = rootResults;
for (DBNNode parent : allParents) {
ResultsNode parentResults = nodeMap.get(parent);
if (parentResults == null) {
parentResults = new ResultsNode(parent, curParentResults);
nodeMap.put(parent, parentResults);
curParentResults.children.add(parentResults);
}
// if (!curParentResults.children.contains(parentResults)) {
// curParentResults.children.add(parentResults);
// }
curParentResults = parentResults;
}
// Make leaf
curParentResults.children.add(new ResultsNode(node, curParentResults));
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册