/* * DBeaver - Universal Database Manager * Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org) * * Licensed 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.jkiss.dbeaver.tools.transfer.database; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.*; import org.jkiss.dbeaver.model.impl.DBObjectNameCaseTransformer; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.sql.SQLUtils; import org.jkiss.dbeaver.model.struct.*; import org.jkiss.utils.CommonUtils; import java.util.ArrayList; import java.util.List; /** * DatabaseMappingAttribute */ class DatabaseMappingAttribute implements DatabaseMappingObject { public static final String TARGET_NAME_SKIP = "[skip]"; final DatabaseMappingContainer parent; DBSAttributeBase source; DBSEntityAttribute target; String targetName; String targetType; DatabaseMappingType mappingType; DatabaseMappingAttribute(DatabaseMappingContainer parent, DBSAttributeBase source) { this.parent = parent; this.source = source; this.mappingType = DatabaseMappingType.unspecified; } public DatabaseMappingContainer getParent() { return parent; } @Override public DBPImage getIcon() { return DBValueFormatting.getObjectImage(source); } @Override public DBSAttributeBase getSource() { return source; } public String getSourceType() { String typeName = source.getTypeName(); if (source.getDataKind() == DBPDataKind.STRING) { typeName += "(" + source.getMaxLength() + ")"; } return typeName; } @Override public String getTargetName() { switch (mappingType) { case existing: if (target != null) { return DBUtils.getObjectFullName(target, DBPEvaluationContext.UI); } else { return targetName; } case create: return targetName; case skip: return TARGET_NAME_SKIP; default: return "?"; } } @Override public DatabaseMappingType getMappingType() { return mappingType; } public void setMappingType(DatabaseMappingType mappingType) { this.mappingType = mappingType; switch (mappingType) { case create: targetName = getSource().getName(); break; } } void updateMappingType(DBRProgressMonitor monitor) throws DBException { switch (parent.getMappingType()) { case existing: { mappingType = DatabaseMappingType.unspecified; if (parent.getTarget() instanceof DBSEntity) { if (CommonUtils.isEmpty(targetName)) { targetName = source.getName(); } target = DBUtils.findObject( ((DBSEntity) parent.getTarget()).getAttributes(monitor), targetName); if (target != null) { mappingType = DatabaseMappingType.existing; } else { mappingType = DatabaseMappingType.create; } } break; } case create: mappingType = DatabaseMappingType.create; if (CommonUtils.isEmpty(targetName)) { targetName = source.getName(); } break; case skip: mappingType = DatabaseMappingType.skip; break; default: mappingType = DatabaseMappingType.unspecified; break; } if (mappingType == DatabaseMappingType.create && !CommonUtils.isEmpty(targetName)) { // Convert target name case (#1516) DBSObjectContainer container = parent.getSettings().getContainer(); if (container != null) { targetName = DBObjectNameCaseTransformer.transformName(container.getDataSource(), targetName); } } } @Override public DBSEntityAttribute getTarget() { return target; } public void setTarget(DBSEntityAttribute target) { this.target = target; } public void setTargetName(String targetName) { this.targetName = targetName; } public String getTargetType(DBPDataSource targetDataSource) { if (!CommonUtils.isEmpty(targetType)) { return targetType; } // TODO: make some smart data type matcher // Current solution looks like hack String typeName = source.getTypeName(); DBPDataKind dataKind = source.getDataKind(); if (targetDataSource instanceof DBPDataTypeProvider) { DBPDataTypeProvider dataTypeProvider = (DBPDataTypeProvider) targetDataSource; DBSDataType dataType = dataTypeProvider.getLocalDataType(typeName); if (dataType == null && typeName.equals("DOUBLE")) { dataType = dataTypeProvider.getLocalDataType("DOUBLE PRECISION"); if (dataType != null) { typeName = dataType.getTypeName(); } } if (dataType != null && dataType.getDataKind() != dataKind) { // Type mismatch dataType = null; } if (dataType == null) { // Type not supported by target database // Let's try to find something similar List<DBSDataType> possibleTypes = new ArrayList<>(); for (DBSDataType type : dataTypeProvider.getLocalDataTypes()) { if (type.getDataKind() == dataKind) { possibleTypes.add(type); } } typeName = DBUtils.getDefaultDataTypeName(targetDataSource, dataKind); if (!possibleTypes.isEmpty()) { DBSDataType targetType = null; for (DBSDataType type : possibleTypes) { if (type.getName().equalsIgnoreCase(typeName)) { targetType = type; break; } } if (targetType == null) { targetType = possibleTypes.get(0); } typeName = targetType.getTypeName(); } } if (dataType != null) { dataKind = dataType.getDataKind(); } } String modifiers = SQLUtils.getColumnTypeModifiers(source, typeName, dataKind); if (modifiers != null) { typeName += modifiers; } return typeName; } public void setTargetType(String targetType) { this.targetType = targetType; } }