提交 447d70d2 编写于 作者: S Serge Rider

#5384 FK create editor (add/remove/constaint mappings)

上级 d8938f20
......@@ -60,7 +60,7 @@ public class MySQLForeignKeyManager extends SQLForeignKeyManager<MySQLTableForei
}
MySQLTableForeignKey foreignKey = new MySQLTableForeignKey(
table,
null,
"",
null,
null,
DBSForeignKeyModifyRule.NO_ACTION,
......
......@@ -305,6 +305,10 @@ public class DBVEntity extends DBVObject implements DBSEntity, DBPQualifiedObjec
return entityConstraints;
}
public List<DBVEntityConstraint> getConstraints() {
return entityConstraints;
}
public DBVEntityConstraint getBestIdentifier() {
if (entityConstraints == null) {
entityConstraints = new ArrayList<>();
......@@ -320,13 +324,19 @@ public class DBVEntity extends DBVObject implements DBSEntity, DBPQualifiedObjec
return entityConstraints.get(0);
}
void addConstraint(DBVEntityConstraint constraint) {
public void addConstraint(DBVEntityConstraint constraint) {
if (entityConstraints == null) {
entityConstraints = new ArrayList<>();
}
entityConstraints.add(constraint);
}
public void removeConstraint(DBVEntityConstraint constraint) {
if (entityConstraints != null) {
entityConstraints.remove(constraint);
}
}
@Nullable
@Override
public synchronized List<DBVEntityForeignKey> getAssociations(@NotNull DBRProgressMonitor monitor) throws DBException {
......
......@@ -56,4 +56,7 @@ public class DBVEntityForeignKeyColumn implements DBSEntityAttributeRef {
return attributeName;
}
public String getRefAttributeName() {
return refAttributeName;
}
}
......@@ -31,6 +31,8 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSDataContainer;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.dbeaver.model.struct.DBSEntityConstraint;
import org.jkiss.utils.CommonUtils;
import java.util.*;
......@@ -214,4 +216,21 @@ public abstract class DBVUtils {
return values;
}
public static List<DBSEntityConstraint> getAllConstraints(DBRProgressMonitor monitor, DBSEntity entity) throws DBException {
List<DBSEntityConstraint> result = new ArrayList<>();
final Collection<? extends DBSEntityConstraint> realConstraints = entity.getConstraints(monitor);
if (!CommonUtils.isEmpty(realConstraints)) {
result.addAll(realConstraints);
}
DBVEntity vEntity = getVirtualEntity(entity, false);
if (vEntity != null) {
List<DBVEntityConstraint> vConstraints = vEntity.getConstraints();
if (!CommonUtils.isEmpty(vConstraints)) {
result.addAll(vConstraints);
}
}
return result;
}
}
......@@ -39,7 +39,7 @@ 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.rdb.*;
import org.jkiss.dbeaver.model.virtual.DBVEntityForeignKey;
import org.jkiss.dbeaver.model.virtual.*;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIUtils;
......@@ -63,6 +63,7 @@ import java.util.List;
public class EditForeignKeyPage extends BaseObjectEditPage {
private static final Log log = Log.getLog(EditForeignKeyPage.class);
private Button customUKButton;
public static class FKColumnInfo {
final DBSEntityAttribute refColumn;
......@@ -102,6 +103,8 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
private DBSForeignKeyModifyRule onDeleteRule;
private DBSForeignKeyModifyRule onUpdateRule;
private boolean enableCustomKeys = false;
public EditForeignKeyPage(
String title,
DBSEntityAssociation foreignKey,
......@@ -112,12 +115,33 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
this.ownerTableNode = DBWorkbench.getPlatform().getNavigatorModel().findNode(foreignKey.getParentObject());
this.supportedModifyRules = supportedModifyRules;
if (ownerTableNode == null) {
try {
if (foreignKey.getParentObject() instanceof DBVEntity) {
DBSEntity realEntity = ((DBVEntity) foreignKey.getParentObject()).getRealEntity(new VoidProgressMonitor());
if (realEntity != null) {
ownerTableNode = DBWorkbench.getPlatform().getNavigatorModel().getNodeByObject(realEntity);
}
}
} catch (DBException e) {
log.error(e);
}
}
if (ownerTableNode != null) {
setImageDescriptor(DBeaverIcons.getImageDescriptor(ownerTableNode.getNodeIcon()));
setTitle(title + " | " + NLS.bind(EditorsMessages.dialog_struct_edit_fk_title, title, ownerTableNode.getNodeName()));
}
}
public boolean isEnableCustomKeys() {
return enableCustomKeys;
}
public void setEnableCustomKeys(boolean enableCustomKeys) {
this.enableCustomKeys = enableCustomKeys;
}
@Override
protected Composite createPageContents(Composite parent) {
final Composite panel = UIUtils.createPlaceholder(parent, 1, 5);
......@@ -129,11 +153,11 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
UIUtils.createLabelText(tableGroup, EditorsMessages.dialog_struct_edit_fk_label_table, DBUtils.getObjectFullName(foreignKey.getParentObject(), DBPEvaluationContext.UI), SWT.READ_ONLY | SWT.BORDER);
try {
if (ownerTableNode != null) {
createSchemaSelector(tableGroup);
} else if (foreignKey instanceof DBVEntityForeignKey) {
if (foreignKey instanceof DBVEntityForeignKey) {
// Virtual key - add container selector
createContainerSelector(tableGroup);
} else if (ownerTableNode != null) {
createSchemaSelector(tableGroup);
}
} catch (Throwable e) {
log.debug("Can't create schema selector", e);
......@@ -161,11 +185,11 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
}
}
final Composite pkGroup = UIUtils.createComposite(panel, 2);
final Composite pkGroup = UIUtils.createComposite(panel, enableCustomKeys ? 3 : 2);
{
pkGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
uniqueKeyCombo = UIUtils.createLabelCombo(pkGroup, EditorsMessages.dialog_struct_edit_fk_combo_unik, SWT.DROP_DOWN | SWT.READ_ONLY);
uniqueKeyCombo.setEnabled(false);
//uniqueKeyCombo.setEnabled(false);
uniqueKeyCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e)
......@@ -173,6 +197,15 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
handleUniqueKeySelect();
}
});
if (enableCustomKeys) {
customUKButton = UIUtils.createDialogButton(pkGroup, "Create", new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
defineRefTableConstraint();
}
});
customUKButton.setEnabled(false);
}
if (supportsCustomName()) {
fkNameText = UIUtils.createLabelText(pkGroup, EditorsMessages.dialog_struct_edit_fk_name, "");
......@@ -240,6 +273,23 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
return panel;
}
private void defineRefTableConstraint() {
if (curRefTable == null) {
log.error("No reference table");
return;
}
DBVEntity vRefEntity = DBVUtils.getVirtualEntity(curRefTable, true);
DBVEntityConstraint constraint = vRefEntity.getBestIdentifier();
EditConstraintPage page = new EditConstraintPage(
"Define unique key",
constraint);
if (page.edit()) {
constraint.setAttributes(page.getSelectedAttributes());
handleRefTableSelect(DBWorkbench.getPlatform().getNavigatorModel().getNodeByObject(curRefTable));
}
}
private void createSchemaSelector(Composite tableGroup) throws DBException {
// Here is a trick - we need to find schema/catalog container node and list its children
DBNDatabaseNode schemaContainerNode = null;
......@@ -324,8 +374,23 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
@Nullable
@Override
protected DBNNode getSelectedNode() {
return DBWorkbench.getPlatform().getNavigatorModel().getNodeByObject(
ownerTableNode != null ? ownerTableNode.getObject() : foreignKey.getDataSource());
DBSObject containerObject;
if (ownerTableNode != null) {
containerObject = ownerTableNode.getObject();
} else {
containerObject = foreignKey.getParentObject();
}
if (containerObject != null && containerObject.getParentObject() instanceof DBSObjectContainer) {
containerObject = containerObject.getParentObject();
}
if (containerObject instanceof DBVContainer) {
try {
containerObject = ((DBVContainer)containerObject).getRealContainer(new VoidProgressMonitor());
} catch (DBException e) {
log.error("Error getting real object container", e);
}
}
return DBWorkbench.getPlatform().getNavigatorModel().getNodeByObject(containerObject);
}
@Override
......@@ -342,6 +407,14 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
containerPanel.setLayoutData(gd);
if (ownerTableNode != null) {
DBNNode containerNode = ownerTableNode.getParentNode();
while (containerNode instanceof DBNDatabaseFolder) {
containerNode = containerNode.getParentNode();
}
containerPanel.setContainerInfo(containerNode.getNodeIconDefault(), containerNode.getNodeFullName());
}
}
private void loadTableList(DBNDatabaseNode newContainerNode) {
......@@ -393,10 +466,7 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
{
if (refTableNode != null) {
DBSObject object = refTableNode.getObject();
if (object == curRefTable) {
// The same selection
return;
} else if (object instanceof DBSEntity) {
if (object instanceof DBSEntity) {
curRefTable = (DBSEntity) refTableNode.getObject();
}
if (fkNameText != null) {
......@@ -420,7 +490,7 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
refTable.getAttributes(monitor);
// Get constraints
final Collection<? extends DBSEntityConstraint> constraints = refTable.getConstraints(monitor);
final Collection<? extends DBSEntityConstraint> constraints = DBVUtils.getAllConstraints(monitor, refTable);
if (!CommonUtils.isEmpty(constraints)) {
for (DBSEntityConstraint constraint : constraints) {
if (constraint.getConstraintType().isUnique()) {
......@@ -450,19 +520,20 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
}
if (uniqueKeyCombo.getItemCount() == 0) {
if (refTableNode == null) {
uniqueKeyCombo.add("<No ref table>");
uniqueKeyCombo.add("<No reference table selected>");
} else {
uniqueKeyCombo.add("<No unique keys found in '" + DBUtils.getObjectFullName(refTableNode.getObject(), DBPEvaluationContext.UI) + "'>");
uniqueKeyCombo.add("<No unique keys in table '" + DBUtils.getObjectFullName(refTableNode.getObject(), DBPEvaluationContext.UI) + "'>");
}
uniqueKeyCombo.select(0);
uniqueKeyCombo.setEnabled(false);
curConstraint = null;
} else {
uniqueKeyCombo.select(0);
uniqueKeyCombo.setEnabled(curConstraints.size() > 1);
if (curConstraints.size() == 1) {
curConstraint = curConstraints.get(0);
}
//uniqueKeyCombo.setEnabled(curConstraints.size() > 1);
curConstraint = curConstraints.get(0);
}
if (enableCustomKeys) {
customUKButton.setEnabled(curConstraint == null);
}
} catch (InvocationTargetException e) {
......@@ -476,27 +547,29 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
private void handleUniqueKeySelect()
{
curConstraint = null;
fkColumns.clear();
ownColumns = null;
columnsTable.removeAll();
if (curConstraints.isEmpty() || uniqueKeyCombo.getSelectionIndex() < 0) {
int ukSelectionIndex = uniqueKeyCombo.getSelectionIndex();
if ((curConstraints.isEmpty() || ukSelectionIndex < 0) && !enableCustomKeys) {
return;
}
curConstraint = curConstraints.get(uniqueKeyCombo.getSelectionIndex());
if (curConstraint instanceof DBSEntityReferrer) {
try {
DBSEntity curEntity = foreignKey.getParentObject();
DBRProgressMonitor monitor = new VoidProgressMonitor();
try {
Collection<? extends DBSEntityAttribute> tmpColumns = curEntity.getAttributes(monitor);
ownColumns = tmpColumns == null ?
Collections.<DBSTableColumn>emptyList() :
new ArrayList<>(getValidAttributes(curEntity));
if (curConstraint instanceof DBSEntityReferrer) {
// Read column nodes with void monitor because we already cached them above
for (DBSEntityAttributeRef pkColumn : ((DBSEntityReferrer)curConstraint).getAttributeReferences(new VoidProgressMonitor())) {
for (DBSEntityAttributeRef pkColumn : ((DBSEntityReferrer)curConstraint).getAttributeReferences(monitor)) {
FKColumnInfo fkColumnInfo = new FKColumnInfo(pkColumn.getAttribute());
// Try to find matched column in own table
Collection<? extends DBSEntityAttribute> tmpColumns = foreignKey.getParentObject().getAttributes(new VoidProgressMonitor());
ownColumns = tmpColumns == null ?
Collections.<DBSTableColumn>emptyList() :
new ArrayList<>(getValidAttributes(foreignKey.getParentObject()));
if (!CommonUtils.isEmpty(ownColumns)) {
for (DBSEntityAttribute ownColumn : ownColumns) {
if (ownColumn.getName().equals(pkColumn.getAttribute().getName()) && foreignKey.getParentObject() != pkColumn.getAttribute().getParentObject()) {
if (ownColumn.getName().equals(pkColumn.getAttribute().getName()) && curEntity != pkColumn.getAttribute().getParentObject()) {
fkColumnInfo.ownColumn = ownColumn;
break;
}
......@@ -515,9 +588,25 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
item.setText(3, pkColumn.getAttribute().getFullTypeName());
item.setData(fkColumnInfo);
}
} catch (DBException e) {
DBWorkbench.getPlatformUI().showError(EditorsMessages.dialog_struct_edit_fk_error_load_constraint_columns_title, EditorsMessages.dialog_struct_edit_fk_error_load_constraint_columns_message, e);
} else if (enableCustomKeys && curRefTable != null) {
for (DBSEntityAttribute attr : CommonUtils.safeCollection(curEntity.getAttributes(monitor))) {
FKColumnInfo fkColumnInfo = new FKColumnInfo(null);
fkColumnInfo.ownColumn = attr;
TableItem item = new TableItem(columnsTable, SWT.NONE);
item.setText(0, fkColumnInfo.ownColumn.getName());
item.setImage(0, getColumnIcon(fkColumnInfo.ownColumn));
item.setText(1, fkColumnInfo.ownColumn.getFullTypeName());
item.setText(2, "");
item.setImage(2, DBeaverIcons.getImage(DBIcon.TYPE_UNKNOWN));
item.setText(3, "");
item.setData(fkColumnInfo);
}
}
} catch (DBException e) {
DBWorkbench.getPlatformUI().showError(
EditorsMessages.dialog_struct_edit_fk_error_load_constraint_columns_title,
EditorsMessages.dialog_struct_edit_fk_error_load_constraint_columns_message, e);
}
UIUtils.packColumns(columnsTable, true);
}
......@@ -600,11 +689,15 @@ public class EditForeignKeyPage extends BaseObjectEditPage {
if (item == null) {
return;
}
FKColumnInfo fkInfo = (FKColumnInfo) item.getData();
int columnIndex = UIUtils.getColumnAtPos(item, e.x, e.y);
if (columnIndex != 0) {
if (fkInfo.ownColumn == null && columnIndex != 0) {
return;
}
final FKColumnInfo fkInfo = (FKColumnInfo) item.getData();
if (fkInfo.refColumn == null && columnIndex != 2) {
return;
}
// Identify the selected row
final CCombo columnsCombo = new CCombo(columnsTable, SWT.DROP_DOWN | SWT.READ_ONLY);
if (!CommonUtils.isEmpty(ownColumns)) {
......
......@@ -29,6 +29,7 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.DBValueFormatting;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.data.DBDAttributeTransformerDescriptor;
......@@ -186,7 +187,10 @@ class EditVirtualEntityDialog extends BaseDialog {
public void widgetSelected(SelectionEvent e) {
DBVEntityForeignKey virtualFK = new DBVEntityForeignKey(vEntity);
EditForeignKeyPage editDialog = new EditForeignKeyPage(
"Define virtual foreign keys", virtualFK, new DBSForeignKeyModifyRule[]{DBSForeignKeyModifyRule.NO_ACTION});
"Define virtual foreign keys",
virtualFK,
new DBSForeignKeyModifyRule[]{DBSForeignKeyModifyRule.NO_ACTION});
editDialog.setEnableCustomKeys(true);
if (!editDialog.edit()) {
return;
}
......@@ -236,9 +240,11 @@ class EditVirtualEntityDialog extends BaseDialog {
if (fk.getReferencedConstraint() != null) {
item.setText(0, fk.getReferencedConstraint().getParentObject().getName());
}
String attrNames = fk.getAttributes().stream().map(DBVEntityForeignKeyColumn::getAttributeName)
String ownAttrNames = fk.getAttributes().stream().map(DBVEntityForeignKeyColumn::getAttributeName)
.collect(Collectors.joining(","));
item.setText(1, attrNames);
String refAttrNames = fk.getAttributes().stream().map(DBVEntityForeignKeyColumn::getRefAttributeName)
.collect(Collectors.joining(","));
item.setText(1, "(" + ownAttrNames + ") -> (" + refAttrNames + ")");
item.setData(fk);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册