Skip to content
Permalink
Browse files

#6745 PG data type resolution fixed. Virtual model: real model listener

  • Loading branch information...
serge-rider committed Oct 9, 2019
1 parent dc156e3 commit 7ea53c89c31a4a39b10ad2d42de8243a5e3898a1
@@ -188,10 +188,6 @@ public String getTargetType(DBPDataSource targetDataSource)
return targetType;
}

// TODO: make some smart data type matcher
// Current solution looks like hack
String typeName = source.getTypeName();
DBPDataKind dataKind = source.getDataKind();
return DBStructUtils.mapTargetDataType(targetDataSource, source);
}

@@ -325,12 +325,21 @@ public DBCExecutionContext getExecutionContext() {
pgTable.setForeignOptions(new String[0]);

for (DBSEntityAttribute attr : CommonUtils.safeCollection(entity.getAttributes(monitor))) {
// Cache data types
PostgreSchema catalogSchema = database.getCatalogSchema(monitor);
if (catalogSchema != null) {
catalogSchema.getDataTypes(monitor);
}
String defTypeName = DBStructUtils.mapTargetDataType(database, attr);
String plainTargetTypeName = SQLUtils.stripColumnTypeModifiers(defTypeName);
PostgreDataType dataType = database.getDataType(monitor, plainTargetTypeName);
if (dataType == null) {
log.error("Data type '" + plainTargetTypeName + "' not found. Skip column mapping.");
continue;
}
PostgreTableColumn newColumn = columnManager.createNewObject(monitor, commandContext, pgTable, null, options);
assert newColumn != null;
newColumn.setName(attr.getName());
String defTypeName = DBStructUtils.mapTargetDataType(database.getDataSource(), attr);
String plainTargetTypeName = SQLUtils.stripColumnTypeModifiers(defTypeName);
PostgreDataType dataType = database.getDataType(monitor, plainTargetTypeName);
newColumn.setDataType(dataType);
}

@@ -863,10 +863,10 @@ public static boolean isIdentifyingAssociation(@NotNull DBRProgressMonitor monit
}

@NotNull
public static String getDefaultDataTypeName(@NotNull DBPDataSource dataSource, DBPDataKind dataKind)
public static String getDefaultDataTypeName(@NotNull DBSObject objectContainer, DBPDataKind dataKind)
{
if (dataSource instanceof DBPDataTypeProvider) {
return ((DBPDataTypeProvider) dataSource).getDefaultDataTypeName(dataKind);
if (objectContainer instanceof DBPDataTypeProvider) {
return ((DBPDataTypeProvider) objectContainer).getDefaultDataTypeName(dataKind);
} else {
// Unsupported data kind
return "?";
@@ -1303,25 +1303,32 @@ public static DBCStatement makeStatement(

public static void fireObjectUpdate(@NotNull DBSObject object)
{
fireObjectUpdate(object, null);
fireObjectUpdate(object, null, null);
}

public static void fireObjectUpdate(DBSObject object, @Nullable Object data)
public static void fireObjectUpdate(DBSObject object, boolean enabled)
{
final DBPDataSourceContainer container = getContainer(object);
if (container != null) {
container.fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, object, data));
container.fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, object, enabled));
}
}

public static void fireObjectUpdate(DBSObject object, boolean enabled)
public static void fireObjectUpdate(DBSObject object, @Nullable Map<String, Object> options, @Nullable Object data)
{
final DBPDataSourceContainer container = getContainer(object);
if (container != null) {
container.fireEvent(new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, object, enabled));
DBPEvent event = new DBPEvent(DBPEvent.Action.OBJECT_UPDATE, object, data);
event.setOptions(options);
container.fireEvent(event);
}
}

public static void fireObjectUpdate(DBSObject object, @Nullable Object data)
{
fireObjectUpdate(object, null, data);
}

public static void fireObjectAdd(DBSObject object, Map<String, Object> options)
{
final DBPDataSourceContainer container = getContainer(object);
@@ -26,6 +26,9 @@
*/
public interface DBEObjectRenamer<OBJECT_TYPE extends DBSObject> extends DBEObjectManager<OBJECT_TYPE> {

String PROP_OLD_NAME = "oldName";
String PROP_NEW_NAME = "newName";

/**
* Describes object
*
@@ -34,6 +34,7 @@
import org.jkiss.utils.CommonUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@@ -384,7 +385,12 @@ public String getNewName() {
public void redoCommand(ObjectRenameCommand command) {
if (command.getObject() instanceof DBPNamedObject2) {
((DBPNamedObject2) command.getObject()).setName(command.newName);
DBUtils.fireObjectUpdate(command.getObject());

Map<String, Object> options = new LinkedHashMap<>();
options.put(DBEObjectRenamer.PROP_OLD_NAME, command.getOldName());
options.put(DBEObjectRenamer.PROP_NEW_NAME, command.getNewName());

DBUtils.fireObjectUpdate(command.getObject(), options, null);
}
}

@@ -185,12 +185,12 @@ private static void addDDLLine(StringBuilder sql, String ddl) {
cyclicTables.addAll(realTables);
}

public static String mapTargetDataType(DBPDataSource targetDataSource, DBSTypedObject typedObject) {
public static String mapTargetDataType(DBSObject objectContainer, DBSTypedObject typedObject) {
String typeName = typedObject.getTypeName();
String typeNameLower = typeName.toLowerCase(Locale.ENGLISH);
DBPDataKind dataKind = typedObject.getDataKind();
if (targetDataSource instanceof DBPDataTypeProvider) {
DBPDataTypeProvider dataTypeProvider = (DBPDataTypeProvider) targetDataSource;
if (objectContainer instanceof DBPDataTypeProvider) {
DBPDataTypeProvider dataTypeProvider = (DBPDataTypeProvider) objectContainer;
DBSDataType dataType = dataTypeProvider.getLocalDataType(typeName);
if (dataType == null && typeNameLower.equals("double")) {
dataType = dataTypeProvider.getLocalDataType("DOUBLE PRECISION");
@@ -245,7 +245,7 @@ public static String mapTargetDataType(DBPDataSource targetDataSource, DBSTypedO
}
}
if (targetType == null) {
typeName = DBUtils.getDefaultDataTypeName(targetDataSource, dataKind);
typeName = DBUtils.getDefaultDataTypeName(objectContainer, dataKind);
typeNameLower = typeName.toLowerCase(Locale.ENGLISH);
if (!possibleTypes.isEmpty()) {
targetType = possibleTypes.get(typeNameLower);
@@ -264,9 +264,9 @@ public static String mapTargetDataType(DBPDataSource targetDataSource, DBSTypedO
}

// Get type modifiers from target datasource
if (targetDataSource instanceof SQLDataSource) {
SQLDialect dialect = ((SQLDataSource) targetDataSource).getSQLDialect();
String modifiers = dialect.getColumnTypeModifiers(targetDataSource, typedObject, typeName, dataKind);
if (objectContainer instanceof SQLDataSource) {
SQLDialect dialect = ((SQLDataSource) objectContainer).getSQLDialect();
String modifiers = dialect.getColumnTypeModifiers((SQLDataSource)objectContainer, typedObject, typeName, dataKind);
if (modifiers != null) {
typeName += modifiers;
}
@@ -109,6 +109,10 @@ public String getRefEntityId() {
return refEntityId;
}

public void setRefEntityId(String refEntityId) {
this.refEntityId = refEntityId;
}

public String getRefConstraintId() {
return refConstraintId;
}
@@ -168,7 +172,8 @@ public DBSEntityConstraint getRealReferenceConstraint(@NotNull DBRProgressMonito

@Override
public DBSEntity getAssociatedEntity() {
return getReferencedConstraint().getParentObject();
DBSEntityConstraint refC = getReferencedConstraint();
return refC == null ? null : refC.getParentObject();
}

@Override
@@ -20,14 +20,14 @@
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.edit.DBEObjectRenamer;
import org.jkiss.dbeaver.model.navigator.DBNDatabaseNode;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSObjectContainer;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.utils.xml.SAXListener;
import org.jkiss.utils.xml.XMLBuilder;

@@ -52,16 +52,14 @@ public DBVModel(@NotNull String id, @NotNull Map<String, Object> map) {
}

public DBVModel(@NotNull DBPDataSourceContainer dataSourceContainer) {
super(null, "model");
super(null, dataSourceContainer.getId());
this.dataSourceContainer = dataSourceContainer;
this.id = dataSourceContainer.getId();
}

// Copy constructor
public DBVModel(@NotNull DBPDataSourceContainer dataSourceContainer, @NotNull DBVModel source) {
super(null, source.getId());
this.dataSourceContainer = dataSourceContainer;
this.id = dataSourceContainer.getId();
this(dataSourceContainer);
copyFrom(source);
}

@@ -214,6 +212,21 @@ static void removeFromCache(@NotNull DBVEntityForeignKey foreignKey) {
}
}

private static void renameEntityInCache(String newRefEntityId, String oldName, String newName) {
String oldRefEntityId = newRefEntityId.replace("/" + newName, "/" + oldName);
synchronized (globalReferenceCache) {
List<DBVEntityForeignKey> fkList = globalReferenceCache.get(oldRefEntityId);
if (fkList != null) {
globalReferenceCache.remove(oldRefEntityId);
globalReferenceCache.put(newRefEntityId, fkList);
for (DBVEntityForeignKey fk : fkList) {
fk.setRefEntityId(newRefEntityId);
fk.getEntity().persistConfiguration();
}
}
}
}

public static void checkGlobalCacheIsEmpty() {
synchronized (globalReferenceCache) {
if (!globalReferenceCache.isEmpty()) {
@@ -222,4 +235,27 @@ public static void checkGlobalCacheIsEmpty() {
}
}

public static class ModelChangeListener implements DBPEventListener {
@Override
public void handleDataSourceEvent(DBPEvent event) {
DBSObject object = event.getObject();
if (event.getAction() == DBPEvent.Action.OBJECT_UPDATE && object instanceof DBSEntity) {
// Handle table renames
Map<String, Object> options = event.getOptions();
if (options != null) {
String oldName = (String)options.get(DBEObjectRenamer.PROP_OLD_NAME);
String newName = (String)options.get(DBEObjectRenamer.PROP_NEW_NAME);
if (oldName != null && newName != null) {
DBNDatabaseNode objectNode = DBWorkbench.getPlatform().getNavigatorModel().getNodeByObject(object);
if (objectNode != null) {
String objectNodePath = objectNode.getNodeItemPath();
renameEntityInCache(objectNodePath, oldName, newName);
System.out.println("Handle rename " + oldName + " into " + newName);
}
}
}
}
}

}
}
@@ -34,6 +34,7 @@
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
import org.jkiss.dbeaver.model.virtual.DBVModel;
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.runtime.resource.DBeaverNature;
@@ -72,12 +73,16 @@
private final List<DBWNetworkProfile> networkProfiles = new ArrayList<>();
private volatile boolean saveInProgress = false;

private final DBVModel.ModelChangeListener modelChangeListener = new DBVModel.ModelChangeListener();

public DataSourceRegistry(DBPPlatform platform, ProjectMetadata project) {
this.platform = platform;
this.project = project;

loadDataSources(false);
DataSourceProviderRegistry.getInstance().fireRegistryChange(this, true);

addDataSourceListener(modelChangeListener);
}

/**
@@ -91,10 +96,13 @@ public DataSourceRegistry(DataSourceRegistry source, ProjectMetadata project, bo
dataSources.add(new DataSourceDescriptor(ds, this));
}
}

addDataSourceListener(modelChangeListener);
}

@Override
public void dispose() {
removeDataSourceListener(modelChangeListener);
DataSourceProviderRegistry.getInstance().fireRegistryChange(this, false);
synchronized (dataSourceListeners) {
if (!this.dataSourceListeners.isEmpty()) {
@@ -781,11 +781,16 @@ private void handleUniqueKeySelect()
if (curConstraint instanceof DBSEntityReferrer) {
// Read column nodes with void monitor because we already cached them above
for (DBSEntityAttributeRef pkColumn : ((DBSEntityReferrer)curConstraint).getAttributeReferences(monitor)) {
FKColumnInfo fkColumnInfo = new FKColumnInfo(pkColumn.getAttribute());
DBSEntityAttribute pkAttribute = pkColumn.getAttribute();
if (pkAttribute == null) {
log.debug("Constraint " + curConstraint.getName() + " column attribute not found");
continue;
}
FKColumnInfo fkColumnInfo = new FKColumnInfo(pkAttribute);
// Try to find matched column in own table
if (!CommonUtils.isEmpty(ownColumns)) {
for (DBSEntityAttribute ownColumn : ownColumns) {
if (ownColumn.getName().equals(pkColumn.getAttribute().getName()) && curEntity != pkColumn.getAttribute().getParentObject()) {
if (ownColumn.getName().equals(pkAttribute.getName()) && curEntity != pkAttribute.getParentObject()) {
fkColumnInfo.ownColumn = ownColumn;
break;
}
@@ -799,9 +804,9 @@ private void handleUniqueKeySelect()
item.setImage(0, getColumnIcon(fkColumnInfo.ownColumn));
item.setText(1, fkColumnInfo.ownColumn.getFullTypeName());
}
item.setText(2, pkColumn.getAttribute().getName());
item.setImage(2, getColumnIcon(pkColumn.getAttribute()));
item.setText(3, pkColumn.getAttribute().getFullTypeName());
item.setText(2, pkAttribute.getName());
item.setImage(2, getColumnIcon(pkAttribute));
item.setText(3, pkAttribute.getFullTypeName());
item.setData(fkColumnInfo);
}
} else if (enableCustomKeys && curRefTable != null) {

0 comments on commit 7ea53c8

Please sign in to comment.
You can’t perform that action at this time.