提交 7afb4e24 编写于 作者: S Serge Rider

Compelx elements add/edit fixes


Former-commit-id: 2d4c86e2
上级 838f6afb
...@@ -35,14 +35,13 @@ import org.jkiss.dbeaver.ModelPreferences; ...@@ -35,14 +35,13 @@ import org.jkiss.dbeaver.ModelPreferences;
import org.jkiss.dbeaver.model.DBPDataSource; import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer; import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPErrorAssistant; import org.jkiss.dbeaver.model.DBPErrorAssistant;
import org.jkiss.dbeaver.model.connection.DBPAuthInfo;
import org.jkiss.dbeaver.model.access.DBAPasswordChangeInfo; import org.jkiss.dbeaver.model.access.DBAPasswordChangeInfo;
import org.jkiss.dbeaver.model.connection.DBPAuthInfo;
import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.connection.DBPDriverDependencies; import org.jkiss.dbeaver.model.connection.DBPDriverDependencies;
import org.jkiss.dbeaver.model.exec.DBExecUtils; import org.jkiss.dbeaver.model.exec.DBExecUtils;
import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor; import org.jkiss.dbeaver.model.runtime.*;
import org.jkiss.dbeaver.model.runtime.DBRProcessListener;
import org.jkiss.dbeaver.model.runtime.load.ILoadService; import org.jkiss.dbeaver.model.runtime.load.ILoadService;
import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer; import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer;
import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSObject;
...@@ -66,6 +65,7 @@ import org.jkiss.dbeaver.ui.views.process.ProcessPropertyTester; ...@@ -66,6 +65,7 @@ import org.jkiss.dbeaver.ui.views.process.ProcessPropertyTester;
import org.jkiss.dbeaver.ui.views.process.ShellProcessView; import org.jkiss.dbeaver.ui.views.process.ShellProcessView;
import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.dbeaver.utils.GeneralUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
...@@ -361,10 +361,18 @@ public class DBeaverUI implements DBPPlatformUI { ...@@ -361,10 +361,18 @@ public class DBeaverUI implements DBPPlatformUI {
} }
@Override @Override
public void executeInUI(@NotNull Runnable runnable) { public void executeWithProgress(@NotNull Runnable runnable) {
UIUtils.syncExec(runnable); UIUtils.syncExec(runnable);
} }
@Override
public void executeWithProgress(@NotNull DBRRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
// FIXME: we need to run with progress service bu we can't change active control focus
// Otherwise it breaks soem functions (e.g. data editor value save as it handles focus events).
// so we can use runInProgressServie function
runnable.run(new VoidProgressMonitor());
}
@NotNull @NotNull
@Override @Override
public <RESULT> Job createLoadingService(ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) { public <RESULT> Job createLoadingService(ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) {
......
...@@ -31,10 +31,8 @@ import org.jkiss.dbeaver.model.impl.DBObjectNameCaseTransformer; ...@@ -31,10 +31,8 @@ import org.jkiss.dbeaver.model.impl.DBObjectNameCaseTransformer;
import org.jkiss.dbeaver.model.impl.data.DBDValueError; import org.jkiss.dbeaver.model.impl.data.DBDValueError;
import org.jkiss.dbeaver.model.impl.data.DefaultValueHandler; import org.jkiss.dbeaver.model.impl.data.DefaultValueHandler;
import org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect; import org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect;
import org.jkiss.dbeaver.model.navigator.DBNDataSource;
import org.jkiss.dbeaver.model.navigator.DBNDatabaseNode;
import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.model.sql.*; import org.jkiss.dbeaver.model.sql.*;
import org.jkiss.dbeaver.model.struct.*; import org.jkiss.dbeaver.model.struct.*;
...@@ -46,6 +44,7 @@ import org.jkiss.dbeaver.utils.RuntimeUtils; ...@@ -46,6 +44,7 @@ import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils; import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
/** /**
...@@ -1851,4 +1850,35 @@ public final class DBUtils { ...@@ -1851,4 +1850,35 @@ public final class DBUtils {
DBPDataSource dataSource = object.getDataSource(); DBPDataSource dataSource = object.getDataSource();
return dataSource == null || !dataSource.getContainer().hasModifyPermission(DBPDataSourcePermission.PERMISSION_EDIT_METADATA); return dataSource == null || !dataSource.getContainer().hasModifyPermission(DBPDataSourcePermission.PERMISSION_EDIT_METADATA);
} }
public static <T> T createNewAttributeValue(DBCExecutionContext context, DBDValueHandler valueHandler, DBSTypedObject valueType, Class<T> targetType) throws DBCException {
DBRRunnableWithResult<Object> runnable = new DBRRunnableWithResult<Object>() {
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
try (DBCSession session = context.openSession(monitor, DBCExecutionPurpose.UTIL, "Create new object")) {
result = valueHandler.createNewValueObject(session, valueType);
} catch (DBCException e) {
throw new InvocationTargetException(e);
}
}
};
try {
DBWorkbench.getPlatformUI().executeWithProgress(runnable);
//UIUtils.runInProgressService(runnable);
} catch (InvocationTargetException e) {
throw new DBCException(e.getTargetException(), context.getDataSource());
} catch (InterruptedException e) {
throw new DBCException(e, context.getDataSource());
}
Object result = runnable.getResult();
if (result == null) {
throw new DBCException("Internal error - null object created");
}
if (!targetType.isInstance(result)) {
throw new DBCException("Internal error - wrong object type '" + result.getClass().getName() + "' while '" + targetType.getName() + "' was expected");
}
return targetType.cast(result);
}
} }
...@@ -20,10 +20,7 @@ import org.jkiss.code.NotNull; ...@@ -20,10 +20,7 @@ import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable; import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.*; import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.struct.DBSAttributeBase; import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.utils.CommonUtils; import org.jkiss.utils.CommonUtils;
/** /**
...@@ -149,6 +146,15 @@ public class DBDAttributeBindingType extends DBDAttributeBindingNested implement ...@@ -149,6 +146,15 @@ public class DBDAttributeBindingType extends DBDAttributeBindingNested implement
return null; return null;
} }
@Nullable
@Override
public DBSDataType getDataType() {
if (attribute instanceof DBSTypedObjectEx) {
return ((DBSTypedObjectEx) attribute).getDataType();
}
return super.getDataType();
}
@Nullable @Nullable
@Override @Override
public DBPImage getObjectImage() { public DBPImage getObjectImage() {
......
...@@ -651,7 +651,7 @@ public class DBNModel implements IResourceChangeListener { ...@@ -651,7 +651,7 @@ public class DBNModel implements IResourceChangeListener {
} }
try { try {
DBWorkbench.getPlatformUI().executeInUI(() -> { DBWorkbench.getPlatformUI().executeWithProgress(() -> {
for (int i = 0; i < realEvents.length; i++) { for (int i = 0; i < realEvents.length; i++) {
for (INavigatorListener listener : listenersCopy) { for (INavigatorListener listener : listenersCopy) {
listener.nodeChanged(realEvents[i]); listener.nodeChanged(realEvents[i]);
......
...@@ -28,10 +28,13 @@ import org.jkiss.dbeaver.model.connection.DBPDriver; ...@@ -28,10 +28,13 @@ import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.connection.DBPDriverDependencies; import org.jkiss.dbeaver.model.connection.DBPDriverDependencies;
import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor; import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.model.runtime.load.ILoadService; import org.jkiss.dbeaver.model.runtime.load.ILoadService;
import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer; import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer;
import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSObject;
import java.lang.reflect.InvocationTargetException;
/** /**
* User interface interactions * User interface interactions
*/ */
...@@ -96,7 +99,9 @@ public interface DBPPlatformUI { ...@@ -96,7 +99,9 @@ public interface DBPPlatformUI {
void executeProcess(@NotNull DBRProcessDescriptor processDescriptor); void executeProcess(@NotNull DBRProcessDescriptor processDescriptor);
// Execute some action in UI thread // Execute some action in UI thread
void executeInUI(@NotNull Runnable runnable); void executeWithProgress(@NotNull Runnable runnable);
void executeWithProgress(@NotNull DBRRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException;
@NotNull @NotNull
<RESULT> Job createLoadingService( <RESULT> Job createLoadingService(
......
...@@ -28,12 +28,16 @@ import org.jkiss.dbeaver.model.connection.DBPDriver; ...@@ -28,12 +28,16 @@ import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.connection.DBPDriverDependencies; import org.jkiss.dbeaver.model.connection.DBPDriverDependencies;
import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.navigator.DBNNode;
import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor; import org.jkiss.dbeaver.model.runtime.DBRProcessDescriptor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
import org.jkiss.dbeaver.model.runtime.LoggingProgressMonitor;
import org.jkiss.dbeaver.model.runtime.load.ILoadService; import org.jkiss.dbeaver.model.runtime.load.ILoadService;
import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer; import org.jkiss.dbeaver.model.runtime.load.ILoadVisualizer;
import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.ui.DBPPlatformUI; import org.jkiss.dbeaver.runtime.ui.DBPPlatformUI;
import java.lang.reflect.InvocationTargetException;
public class ConsoleUserInterface implements DBPPlatformUI { public class ConsoleUserInterface implements DBPPlatformUI {
@Override @Override
public UserResponse showError(@NotNull String title, @Nullable String message, @NotNull IStatus status) { public UserResponse showError(@NotNull String title, @Nullable String message, @NotNull IStatus status) {
...@@ -143,10 +147,15 @@ public class ConsoleUserInterface implements DBPPlatformUI { ...@@ -143,10 +147,15 @@ public class ConsoleUserInterface implements DBPPlatformUI {
} }
@Override @Override
public void executeInUI(@NotNull Runnable runnable) { public void executeWithProgress(@NotNull Runnable runnable) {
runnable.run(); runnable.run();
} }
@Override
public void executeWithProgress(@NotNull DBRRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
runnable.run(new LoggingProgressMonitor());
}
@NotNull @NotNull
@Override @Override
public <RESULT> Job createLoadingService(ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) { public <RESULT> Job createLoadingService(ILoadService<RESULT> loadingService, ILoadVisualizer<RESULT> visualizer) {
......
...@@ -22,6 +22,7 @@ import org.eclipse.swt.graphics.Color; ...@@ -22,6 +22,7 @@ import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
import org.jkiss.code.NotNull; import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable; import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ModelPreferences; import org.jkiss.dbeaver.ModelPreferences;
import org.jkiss.dbeaver.model.DBPDataKind; import org.jkiss.dbeaver.model.DBPDataKind;
...@@ -32,6 +33,7 @@ import org.jkiss.dbeaver.model.exec.*; ...@@ -32,6 +33,7 @@ import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.exec.trace.DBCTrace; import org.jkiss.dbeaver.model.exec.trace.DBCTrace;
import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.model.struct.*; import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.model.virtual.DBVColorOverride; import org.jkiss.dbeaver.model.virtual.DBVColorOverride;
import org.jkiss.dbeaver.model.virtual.DBVEntity; import org.jkiss.dbeaver.model.virtual.DBVEntity;
...@@ -354,7 +356,7 @@ public class ResultSetModel { ...@@ -354,7 +356,7 @@ public class ResultSetModel {
for (int i = 0; i < depth; i++) { for (int i = 0; i < depth; i++) {
if (ownerValue == null) { if (ownerValue == null) {
// Create new owner object // Create new owner object
log.warn("Null owner value"); log.warn("Null owner value for '" + attr.getName() + "', row " + row.getVisualNumber());
return false; return false;
} }
if (i == depth - 1) { if (i == depth - 1) {
...@@ -363,7 +365,32 @@ public class ResultSetModel { ...@@ -363,7 +365,32 @@ public class ResultSetModel {
DBDAttributeBinding ownerAttr = attr.getParent(depth - i - 1); DBDAttributeBinding ownerAttr = attr.getParent(depth - i - 1);
assert ownerAttr != null; assert ownerAttr != null;
try { try {
ownerValue = ownerAttr.extractNestedValue(ownerValue); Object nestedValue = ownerAttr.extractNestedValue(ownerValue);
if (nestedValue == null) {
// Try to create nested value
DBCExecutionContext context = DBUtils.getDefaultContext(ownerAttr, false);
nestedValue = DBUtils.createNewAttributeValue(context, ownerAttr.getValueHandler(), ownerAttr.getAttribute(), DBDComplexValue.class);
if (ownerValue instanceof DBDComposite) {
((DBDComposite) ownerValue).setAttributeValue(ownerAttr, nestedValue);
}
if (ownerAttr.getDataKind() == DBPDataKind.ARRAY) {
// That's a tough case. Collection of elements. We need to create first element in this collection
if (nestedValue instanceof DBDCollection) {
Object elemValue = null;
try {
DBSDataType componentType = ((DBDCollection) nestedValue).getComponentType();
DBDValueHandler elemValueHandler = DBUtils.findValueHandler(context.getDataSource(), componentType);
elemValue = DBUtils.createNewAttributeValue(context, elemValueHandler, componentType, DBDComplexValue.class);
} catch (DBException e) {
log.warn("Error while getting component type name", e);
}
((DBDCollection) nestedValue).setContents(new Object[] { elemValue } );
} else {
log.warn("Attribute '" + ownerAttr.getName() + "' has collection type but attribute value is not a collection: " + nestedValue);
}
}
}
ownerValue = nestedValue;
} catch (DBCException e) { } catch (DBCException e) {
log.warn("Error getting field [" + ownerAttr.getName() + "] value", e); log.warn("Error getting field [" + ownerAttr.getName() + "] value", e);
return false; return false;
...@@ -387,6 +414,12 @@ public class ResultSetModel { ...@@ -387,6 +414,12 @@ public class ResultSetModel {
} }
// Check composite type // Check composite type
if (ownerValue != null) { if (ownerValue != null) {
if (ownerValue instanceof DBDCollection) {
DBDCollection collection = (DBDCollection) ownerValue;
if (collection.getItemCount() > 0) {
ownerValue = collection.getItem(0);
}
}
if (!(ownerValue instanceof DBDComposite)) { if (!(ownerValue instanceof DBDComposite)) {
log.warn("Value [" + ownerValue + "] edit is not supported"); log.warn("Value [" + ownerValue + "] edit is not supported");
return false; return false;
......
...@@ -802,7 +802,11 @@ public class ComplexObjectEditor extends TreeViewer { ...@@ -802,7 +802,11 @@ public class ComplexObjectEditor extends TreeViewer {
ComplexElement[] arrayItems = childrenMap.get(collection); ComplexElement[] arrayItems = childrenMap.get(collection);
if (collection == null) { if (collection == null) {
try { try {
collection = createNewObject(DBDCollection.class); collection = DBUtils.createNewAttributeValue(
parentController.getExecutionContext(),
parentController.getValueHandler(),
parentController.getValueType(),
DBDCollection.class);
setInput(collection); setInput(collection);
} catch (DBCException e) { } catch (DBCException e) {
DBWorkbench.getPlatformUI().showError("New object create", "Error creating new collection", e); DBWorkbench.getPlatformUI().showError("New object create", "Error creating new collection", e);
...@@ -836,35 +840,6 @@ public class ComplexObjectEditor extends TreeViewer { ...@@ -836,35 +840,6 @@ public class ComplexObjectEditor extends TreeViewer {
autoUpdateComplexValue(); autoUpdateComplexValue();
} }
private <T> T createNewObject(Class<T> targetType) throws DBCException {
DBRRunnableWithResult<Object> runnable = new DBRRunnableWithResult<Object>() {
@Override
public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.UTIL, "Create new object")) {
result = parentController.getValueHandler().createNewValueObject(session, parentController.getValueType());
} catch (DBCException e) {
throw new InvocationTargetException(e);
}
}
};
try {
UIUtils.runInProgressService(runnable);
} catch (InvocationTargetException e) {
throw new DBCException(e.getTargetException(), executionContext.getDataSource());
} catch (InterruptedException e) {
throw new DBCException(e, executionContext.getDataSource());
}
Object result = runnable.getResult();
if (result == null) {
throw new DBCException("Internal error - null object created");
}
if (!targetType.isInstance(result)) {
throw new DBCException("Internal error - wrong object type '" + result.getClass().getName() + "' while '" + targetType.getName() + "' was expected");
}
return targetType.cast(result);
}
} }
private class RemoveElementAction extends Action { private class RemoveElementAction extends Action {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册