未验证 提交 f532129c 编写于 作者: A Anastasiya 提交者: GitHub

#15733 ability to add recreate mapping status for non existing tables… (#15888)

* #15733 ability to add recreate mapping status for non existing tables added; keep recreate status in task editor

* #15733 keep create status for recreate table columns in tasks

* #15733 check cache after table recreating; fix data import in the recreated table

* #15733 add extra code comments

* #15733 refactor update attribute mapping code
上级 63edb3a4
......@@ -28,22 +28,12 @@ import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.swt.widgets.*;
import org.jkiss.code.NotNull;
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.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPDataSourcePermission;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.edit.DBEPersistAction;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
......@@ -65,11 +55,7 @@ import org.jkiss.dbeaver.tools.transfer.registry.DataTransferAttributeTransforme
import org.jkiss.dbeaver.tools.transfer.registry.DataTransferRegistry;
import org.jkiss.dbeaver.tools.transfer.ui.internal.DTUIMessages;
import org.jkiss.dbeaver.tools.transfer.ui.pages.DataTransferPageNodeSettings;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.DefaultViewerToolTipSupport;
import org.jkiss.dbeaver.ui.SharedTextColors;
import org.jkiss.dbeaver.ui.UIIcon;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.*;
import org.jkiss.dbeaver.ui.controls.CustomComboBoxCellEditor;
import org.jkiss.dbeaver.ui.controls.ObjectContainerSelectorPanel;
import org.jkiss.dbeaver.ui.controls.TreeContentProvider;
......@@ -79,9 +65,8 @@ import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
......@@ -530,10 +515,8 @@ public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
return newName;
}
if (mapping instanceof DatabaseMappingContainer) {
if (mapping.getMappingType() == DatabaseMappingType.existing || mapping.getMappingType() == DatabaseMappingType.recreate) {
return ((DatabaseMappingContainer) mapping).getTarget();
}
return mapping.getTargetName();
DBSDataManipulator target = ((DatabaseMappingContainer) mapping).getTarget();
return target != null ? target : mapping.getTargetName();
} else {
if (mapping.getMappingType() == DatabaseMappingType.existing) {
return ((DatabaseMappingAttribute) mapping).getTarget();
......@@ -587,10 +570,16 @@ public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
mappingTypes.add(mappingType.name());
}
if (mapping instanceof DatabaseMappingContainer) {
if (mappingType == DatabaseMappingType.existing) {
if (mappingType == DatabaseMappingType.existing || mappingType == DatabaseMappingType.create) {
// Recreate can be used for not-existing in this moment tables if user will save this mapping in the task
mappingTypes.add(DatabaseMappingType.recreate.name());
} else if (mappingType == DatabaseMappingType.recreate) {
mappingTypes.add(DatabaseMappingType.existing.name());
// Depends on the existence of the target table
if (mapping.getTarget() != null) {
mappingTypes.add(DatabaseMappingType.existing.name());
} else {
mappingTypes.add(DatabaseMappingType.create.name());
}
}
}
if (mapping instanceof DatabaseMappingAttribute) {
......@@ -623,7 +612,8 @@ public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
try {
DatabaseMappingObject mapping = (DatabaseMappingObject) element;
DatabaseMappingType mappingType = DatabaseMappingType.valueOf(value.toString());
if (mappingType == DatabaseMappingType.recreate) {
if (mapping.getMappingType() != DatabaseMappingType.recreate && mappingType == DatabaseMappingType.recreate) {
// Show this confirmation if mapping is not recreate at this moment
boolean confirmed = UIUtils.confirmAction(
getShell(),
DTUIMessages.database_consumer_page_mapping_recreate_confirm_title,
......@@ -831,8 +821,13 @@ public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
String unQuotedNameForSearch = DBUtils.getUnQuotedIdentifier(container.getDataSource(), name);
for (DBSObject child : container.getChildren(new VoidProgressMonitor())) {
if (child instanceof DBSDataManipulator && unQuotedNameForSearch.equalsIgnoreCase(child.getName())) {
containerMapping.setTarget((DBSDataManipulator)child);
containerMapping.refreshMappingType(getWizard().getRunnableContext(), DatabaseMappingType.existing, false);
containerMapping.setTarget((DBSDataManipulator) child);
if (forceRefresh && mapping.getMappingType() == DatabaseMappingType.recreate) {
// Keep container mapping type, refresh only attributes
containerMapping.refreshOnlyAttributesMappingTypes(getWizard().getRunnableContext(),false);
} else {
containerMapping.refreshMappingType(getWizard().getRunnableContext(), DatabaseMappingType.existing, false);
}
DataTransferPipe pipeFromCurrentSelection = getPipeFromCurrentSelection();
if (pipeFromCurrentSelection != null) {
IDataTransferConsumer<?, ?> consumer = pipeFromCurrentSelection.getConsumer();
......@@ -845,9 +840,14 @@ public class DatabaseConsumerPageMapping extends DataTransferPageNodeSettings {
}
}
}
containerMapping.refreshMappingType(getWizard().getRunnableContext(), DatabaseMappingType.create, forceRefresh);
((DatabaseMappingContainer) mapping).setTarget(null);
((DatabaseMappingContainer) mapping).setTargetName(name);
if (forceRefresh && mapping.getMappingType() == DatabaseMappingType.recreate) {
// Keep container mapping type, refresh only attributes
containerMapping.refreshOnlyAttributesMappingTypes(getWizard().getRunnableContext(),false);
} else {
containerMapping.refreshMappingType(getWizard().getRunnableContext(), DatabaseMappingType.create, forceRefresh);
((DatabaseMappingContainer) mapping).setTarget(null);
((DatabaseMappingContainer) mapping).setTargetName(name);
}
} else {
DatabaseMappingAttribute attrMapping = (DatabaseMappingAttribute) mapping;
DBPDataSource targetDataSource = settings.getTargetDataSource(mapping);
......
......@@ -144,88 +144,84 @@ public class DatabaseMappingAttribute implements DatabaseMappingObject {
}
public void updateMappingType(DBRProgressMonitor monitor, boolean forceRefresh) throws DBException {
switch (parent.getMappingType()) {
case recreate:
case existing: {
if (mappingType == DatabaseMappingType.skip) {
// We already have mapping for the attribute with the skip type
break;
}
mappingType = DatabaseMappingType.unspecified;
if (parent.getTarget() instanceof DBSEntity) {
if (forceRefresh || CommonUtils.isEmpty(targetName)) {
targetName = getSourceLabelOrName(source, true);
}
DBSEntity targetEntity = (DBSEntity) parent.getTarget();
List<? extends DBSEntityAttribute> targetAttributes = targetEntity.getAttributes(monitor);
if (targetAttributes != null) {
if (mappingType == DatabaseMappingType.skip) {
// We already have mapping for the attribute with the skip type
return;
}
if (parent.getMappingType() == DatabaseMappingType.skip) {
mappingType = DatabaseMappingType.skip;
return;
}
mappingType = DatabaseMappingType.unspecified;
if (parent.getTarget() instanceof DBSEntity) {
if (forceRefresh || CommonUtils.isEmpty(targetName)) {
targetName = getSourceLabelOrName(source, true);
}
DBSEntity targetEntity = (DBSEntity) parent.getTarget();
List<? extends DBSEntityAttribute> targetAttributes = targetEntity.getAttributes(monitor);
if (CommonUtils.isEmpty(targetAttributes) && targetEntity instanceof DBPRefreshableObject) {
// Reload table attributes cache. It can be empty after table deleting
((DBPRefreshableObject) targetEntity).refreshObject(monitor);
targetAttributes = targetEntity.getAttributes(monitor);
}
if (targetAttributes != null) {
target = CommonUtils.findBestCaseAwareMatch(
targetAttributes,
DBUtils.getUnQuotedIdentifier(targetEntity.getDataSource(), targetName),
DBSEntityAttribute::getName
);
} else {
target = null;
}
if (source instanceof StreamDataImporterColumnInfo && targetAttributes != null) {
StreamDataImporterColumnInfo source = (StreamDataImporterColumnInfo) this.source;
if (!source.isMappingMetadataPresent()) {
List<DBSEntityAttribute> suitableTargetAttributes = targetAttributes
.stream()
.filter(attr -> !DBUtils.isPseudoAttribute(attr) && !DBUtils.isHiddenObject(attr))
.sorted(Comparator.comparing(DBSEntityAttribute::getOrdinalPosition))
.collect(Collectors.toList());
if (source.getOrdinalPosition() < suitableTargetAttributes.size()) {
DBSEntityAttribute targetAttribute = suitableTargetAttributes.get(source.getOrdinalPosition());
target = CommonUtils.findBestCaseAwareMatch(
targetAttributes,
DBUtils.getUnQuotedIdentifier(targetEntity.getDataSource(), targetName),
DBSEntityAttribute::getName
);
} else {
target = null;
}
if (source instanceof StreamDataImporterColumnInfo && targetAttributes != null) {
StreamDataImporterColumnInfo source = (StreamDataImporterColumnInfo) this.source;
if (!source.isMappingMetadataPresent()) {
List<DBSEntityAttribute> suitableTargetAttributes = targetAttributes
.stream()
.filter(attr -> !DBUtils.isPseudoAttribute(attr) && !DBUtils.isHiddenObject(attr))
.sorted(Comparator.comparing(DBSEntityAttribute::getOrdinalPosition))
.collect(Collectors.toList());
if (source.getOrdinalPosition() < suitableTargetAttributes.size()) {
DBSEntityAttribute targetAttribute = suitableTargetAttributes.get(source.getOrdinalPosition());
target = CommonUtils.findBestCaseAwareMatch(
targetAttributes,
DBUtils.getUnQuotedIdentifier(targetEntity.getDataSource(), targetName),
DBSEntityAttribute::getName
);
if (target != null && !targetAttribute.getName().equalsIgnoreCase(target.getName())) {
// In case of violated order (some columns are missing in the source, for example), if it turned out to find a suitable column by name
targetName = target.getName();
} else {
targetName = targetAttribute.getName();
}
}
}
if (target != null) {
source.setTypeName(target.getTypeName());
source.setMaxLength(target.getMaxLength());
source.setDataKind(target.getDataKind());
}
}
if (this.target != null) {
if (parent.getMappingType() == DatabaseMappingType.recreate) {
mappingType = DatabaseMappingType.create;
if (target != null && !targetAttribute.getName().equalsIgnoreCase(target.getName())) {
// In case of violated order (some columns are missing in the source, for example), if it turned out to find a suitable column by name
targetName = target.getName();
} else {
mappingType = DatabaseMappingType.existing;
targetName = targetAttribute.getName();
}
} else {
mappingType = DatabaseMappingType.create;
}
}
break;
if (target != null) {
source.setTypeName(target.getTypeName());
source.setMaxLength(target.getMaxLength());
source.setDataKind(target.getDataKind());
}
}
case create:
if (mappingType != DatabaseMappingType.skip) { // We already have mapping for the attribute with the skip type
if (this.target != null) {
if (parent.getMappingType() == DatabaseMappingType.recreate) {
mappingType = DatabaseMappingType.create;
} else {
mappingType = DatabaseMappingType.existing;
}
if (forceRefresh || CommonUtils.isEmpty(targetName)) {
targetName = getSourceLabelOrName(source, true);
}
break;
case skip:
mappingType = DatabaseMappingType.skip;
break;
default:
mappingType = DatabaseMappingType.unspecified;
break;
} else {
mappingType = DatabaseMappingType.create;
}
} else {
// Case recreate container mapping in the new table or just create
mappingType = DatabaseMappingType.create;
if (forceRefresh || CommonUtils.isEmpty(targetName)) {
targetName = getSourceLabelOrName(source, true);
}
}
if (mappingType == DatabaseMappingType.create && !CommonUtils.isEmpty(targetName)) {
......@@ -349,8 +345,8 @@ public class DatabaseMappingAttribute implements DatabaseMappingObject {
}
}
if (target != null && newMappingType == DatabaseMappingType.create) {
// Change create to existing.
if (target != null && newMappingType == DatabaseMappingType.create && parent.getMappingType() != DatabaseMappingType.recreate) {
// Change create to existing. Do not change mapping type for the recreate type
newMappingType = DatabaseMappingType.existing;
} else if (target == null && newMappingType == DatabaseMappingType.existing) {
newMappingType = DatabaseMappingType.create;
......
......@@ -105,8 +105,16 @@ public class DatabaseMappingContainer implements DatabaseMappingObject {
refreshMappingType(new VoidProgressMonitor(), mappingType, forceRefresh);
}
public void refreshOnlyAttributesMappingTypes(DBRRunnableContext context, boolean forceRefresh) throws DBException {
refreshAttributesMappingTypes(new VoidProgressMonitor(), forceRefresh);
}
private void refreshMappingType(DBRProgressMonitor monitor, DatabaseMappingType mappingType, boolean forceRefresh) throws DBException {
this.mappingType = mappingType;
refreshAttributesMappingTypes(monitor, forceRefresh);
}
private void refreshAttributesMappingTypes(DBRProgressMonitor monitor, boolean forceRefresh) throws DBException {
final Collection<DatabaseMappingAttribute> mappings = getAttributeMappings(monitor);
if (!CommonUtils.isEmpty(mappings)) {
for (DatabaseMappingAttribute attr : mappings) {
......@@ -179,11 +187,13 @@ public class DatabaseMappingContainer implements DatabaseMappingObject {
switch (mappingType) {
case existing:
case recreate:
return target.getName();
case create:
if (target != null) {
return target.getName();
}
return targetTableName;
case skip:
return DatabaseMappingAttribute.TARGET_NAME_SKIP;
case create:
default:
return targetTableName;
}
......@@ -277,7 +287,7 @@ public class DatabaseMappingContainer implements DatabaseMappingObject {
if (target != null && newMappingType == DatabaseMappingType.create) {
// Change create to existing.
newMappingType = DatabaseMappingType.existing;
} else if (target == null && (newMappingType == DatabaseMappingType.existing || newMappingType == DatabaseMappingType.recreate)) {
} else if (target == null && newMappingType == DatabaseMappingType.existing) {
newMappingType = DatabaseMappingType.create;
}
refreshMappingType(context, newMappingType, false);
......
......@@ -35,7 +35,6 @@ import org.jkiss.dbeaver.model.navigator.DBNEvent;
import org.jkiss.dbeaver.model.navigator.DBNUtils;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.model.sql.SQLState;
import org.jkiss.dbeaver.model.sql.registry.SQLInsertReplaceMethodDescriptor;
import org.jkiss.dbeaver.model.sql.registry.SQLInsertReplaceMethodRegistry;
import org.jkiss.dbeaver.model.struct.*;
......@@ -653,10 +652,8 @@ public class DatabaseTransferConsumer implements IDataTransferConsumer<DatabaseC
throw new DBException("No target container selected");
}
if (session.getDataSource().getInfo().isDynamicMetadata()) {
if (containerMapping.getMappingType() == DatabaseMappingType.recreate) {
DatabaseTransferUtils.createTargetDynamicTable(session.getProgressMonitor(), session.getExecutionContext(), schema, containerMapping, true);
} else if (containerMapping.getMappingType() == DatabaseMappingType.create) {
DatabaseTransferUtils.createTargetDynamicTable(session.getProgressMonitor(), session.getExecutionContext(), schema, containerMapping, false);
if (containerMapping.getMappingType() == DatabaseMappingType.recreate || containerMapping.getMappingType() == DatabaseMappingType.create) {
DatabaseTransferUtils.createTargetDynamicTable(session.getProgressMonitor(), session.getExecutionContext(), schema, containerMapping, containerMapping.getTarget() != null);
}
return true;
} else {
......
......@@ -68,6 +68,7 @@ public class DatabaseTransferUtils {
{
switch (containerMapping.getMappingType()) {
case create:
case recreate:
DBSObject newTarget = container.getChild(monitor, DBUtils.getUnQuotedIdentifier(container.getDataSource(), containerMapping.getTargetName()));
if (newTarget == null) {
throw new DBCException("New table " + containerMapping.getTargetName() + " not found in container " + DBUtils.getObjectFullName(container, DBPEvaluationContext.UI));
......@@ -75,7 +76,9 @@ public class DatabaseTransferUtils {
throw new DBCException("New table " + DBUtils.getObjectFullName(newTarget, DBPEvaluationContext.UI) + " doesn't support data manipulation");
}
containerMapping.setTarget((DBSDataManipulator) newTarget);
containerMapping.setMappingType(DatabaseMappingType.existing);
if (containerMapping.getMappingType() == DatabaseMappingType.create) {
containerMapping.setMappingType(DatabaseMappingType.existing);
}
// ! Fall down is ok here
case existing:
for (DatabaseMappingAttribute attr : containerMapping.getAttributeMappings(monitor)) {
......@@ -125,13 +128,13 @@ public class DatabaseTransferUtils {
List<DBEPersistAction> actions = new ArrayList<>();
if (containerMapping.getMappingType() == DatabaseMappingType.recreate) {
if (containerMapping.getMappingType() == DatabaseMappingType.recreate && containerMapping.getTarget() != null) {
sql.append("DROP TABLE ");
getTableFullName(schema, dataSource, sql, tableName);
sql.append(dataSource.getSQLDialect().getScriptDelimiters()[0]);
}
if (containerMapping.getMappingType() == DatabaseMappingType.create) {
if (containerMapping.getMappingType() == DatabaseMappingType.create || containerMapping.getMappingType() == DatabaseMappingType.recreate) {
sql.append("CREATE TABLE ");
getTableFullName(schema, dataSource, sql, tableName);
sql.append("(\n");
......@@ -230,7 +233,9 @@ public class DatabaseTransferUtils {
DBSEntity table;
DBECommand createCommand = null;
if (containerMapping.getMappingType() == DatabaseMappingType.create) {
if (containerMapping.getMappingType() == DatabaseMappingType.create ||
(containerMapping.getMappingType() == DatabaseMappingType.recreate && containerMapping.getTarget() == null))
{
table = tableManager.createNewObject(monitor, commandContext, schema, null, options);
tableFinalName = getTableFinalName(containerMapping.getTargetName(), tableClass, table);
createCommand = tableManager.makeCreateCommand(table, options);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册