Просмотр исходного кода

#18522 Keep datasource's original provider and driver IDs (#18864)

ShadelessFox 3 лет назад
Родитель
Сommit
eba9488aec

+ 23 - 2
plugins/org.jkiss.dbeaver.registry/src/org/jkiss/dbeaver/registry/DataSourceDescriptor.java

@@ -110,6 +110,8 @@ public class DataSourceDescriptor
     @NotNull
     private DBPDriver driver;
     @NotNull
+    private DBPDriver originalDriver;
+    @NotNull
     private DBPConnectionConfiguration connectionInfo;
     // Copy of connection info with resolved params (cache)
     private DBPConnectionConfiguration resolvedConnectionInfo;
@@ -187,13 +189,27 @@ public class DataSourceDescriptor
         @NotNull DBPDataSourceOrigin origin,
         @NotNull String id,
         @NotNull DBPDriver driver,
-        @NotNull DBPConnectionConfiguration connectionInfo) {
+        @NotNull DBPConnectionConfiguration connectionInfo
+    ) {
+        this(registry, storage, origin, id, driver, driver, connectionInfo);
+    }
+
+    public DataSourceDescriptor(
+        @NotNull DBPDataSourceRegistry registry,
+        @NotNull DBPDataSourceConfigurationStorage storage,
+        @NotNull DBPDataSourceOrigin origin,
+        @NotNull String id,
+        @NotNull DBPDriver originalDriver,
+        @NotNull DBPDriver substitutedDriver,
+        @NotNull DBPConnectionConfiguration connectionInfo
+    ) {
         this.registry = registry;
         this.storage = storage;
         this.origin = origin;
         this.manageable = storage.isDefault();
         this.id = id;
-        this.driver = driver;
+        this.originalDriver = originalDriver;
+        this.driver = substitutedDriver;
         this.connectionInfo = connectionInfo;
         this.preferenceStore = new DataSourcePreferenceStore(this);
         this.virtualModel = new DBVModel(this);
@@ -292,6 +308,11 @@ public class DataSourceDescriptor
         return driver;
     }
 
+    @NotNull
+    public DBPDriver getOriginalDriver() {
+        return originalDriver;
+    }
+
     @NotNull
     @Override
     public DBPDataSourceConfigurationStorage getConfigurationStorage() {

+ 24 - 0
plugins/org.jkiss.dbeaver.registry/src/org/jkiss/dbeaver/registry/DataSourceProviderDescriptor.java

@@ -19,6 +19,7 @@ package org.jkiss.dbeaver.registry;
 
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.jkiss.code.NotNull;
+import org.jkiss.code.Nullable;
 import org.jkiss.dbeaver.Log;
 import org.jkiss.dbeaver.model.DBIcon;
 import org.jkiss.dbeaver.model.DBPDataSourceProvider;
@@ -334,6 +335,12 @@ public class DataSourceProviderDescriptor extends AbstractDescriptor implements
         return eDrivers;
     }
 
+    /**
+     * Retrieves an original or, if another one replaced it, substituted driver by the given {@code id}.
+     *
+     * @param id identifier of the driver to retrieve
+     * @return driver or {@code null} if no driver was found
+     */
     public DriverDescriptor getDriver(String id)
     {
         for (DriverDescriptor driver : drivers) {
@@ -347,6 +354,23 @@ public class DataSourceProviderDescriptor extends AbstractDescriptor implements
         return null;
     }
 
+    /**
+     * Retrieves a driver by the given {@code id}.
+     *
+     * @param id identifier of the driver to retrieve
+     * @return driver or {@code null} if no driver was found
+     */
+    @Nullable
+    public DriverDescriptor getOriginalDriver(@NotNull String id) {
+        for (DriverDescriptor driver : drivers) {
+            if (driver.getId().equals(id)) {
+                return driver;
+            }
+        }
+
+        return null;
+    }
+
     public DriverDescriptor createDriver()
     {
         return createDriver(SecurityUtils.generateGUID(false));

+ 75 - 20
plugins/org.jkiss.dbeaver.registry/src/org/jkiss/dbeaver/registry/DataSourceSerializerModern.java

@@ -63,6 +63,9 @@ class DataSourceSerializerModern implements DataSourceSerializer
     static final String ATTR_NAVIGATOR_HIDE_VIRTUAL = "navigator-hide-virtual"; //$NON-NLS-1$
     static final String ATTR_NAVIGATOR_MERGE_ENTITIES = "navigator-merge-entities"; //$NON-NLS-1$
 
+    private static final String ATTR_ORIGINAL_PROVIDER = "original-provider"; //$NON-NLS-1$
+    private static final String ATTR_ORIGINAL_DRIVER = "original-driver"; //$NON-NLS-1$
+
     public static final String TAG_ORIGIN = "origin"; //$NON-NLS-1$
     private static final String ATTR_ORIGIN_TYPE = "$type"; //$NON-NLS-1$
     private static final String ATTR_ORIGIN_CONFIGURATION = "$configuration"; //$NON-NLS-1$
@@ -498,28 +501,29 @@ class DataSourceSerializerModern implements DataSourceSerializer
                 String id = conMap.getKey();
                 Map<String, Object> conObject = conMap.getValue();
 
-                // Primary settings
-                String dsProviderID = CommonUtils.toString(conObject.get(RegistryConstants.ATTR_PROVIDER));
-                if (CommonUtils.isEmpty(dsProviderID)) {
-                    log.debug("Empty datasource provider for datasource '" + id + "'");
+                final String originalProviderId = CommonUtils.toString(conObject.get(ATTR_ORIGINAL_PROVIDER));
+                final String originalDriverId = CommonUtils.toString(conObject.get(ATTR_ORIGINAL_DRIVER));
+                final String substitutedProviderId = CommonUtils.toString(conObject.get(RegistryConstants.ATTR_PROVIDER));
+                final String substitutedDriverId = CommonUtils.toString(conObject.get(RegistryConstants.ATTR_DRIVER));
+
+                DriverDescriptor originalDriver;
+                DriverDescriptor substitutedDriver;
+
+                if (CommonUtils.isEmpty(originalProviderId) || CommonUtils.isEmpty(originalDriverId)) {
+                    originalDriver = parseDriver(id, substitutedProviderId, substitutedDriverId, true);
+                    substitutedDriver = originalDriver;
+                } else {
+                    originalDriver = parseDriver(id, originalProviderId, originalDriverId, true);
+                    substitutedDriver = parseDriver(id, substitutedProviderId, substitutedDriverId, false);
+                }
+                if (originalDriver == null) {
                     continue;
                 }
-                DataSourceProviderDescriptor provider = DataSourceProviderRegistry.getInstance().getDataSourceProvider(
-                    dsProviderID);
-                if (provider == null) {
-                    log.debug("Can't find datasource provider " + dsProviderID + " for datasource '" + id + "'");
-                    provider = (DataSourceProviderDescriptor) DataSourceProviderRegistry.getInstance().makeFakeProvider(dsProviderID);
+                if (substitutedDriver == null || substitutedDriver.isTemporary()) {
+                    substitutedDriver = originalDriver;
                 }
-                String driverId = CommonUtils.toString(conObject.get(RegistryConstants.ATTR_DRIVER));
-                DriverDescriptor driver = provider.getDriver(driverId);
-                if (driver == null) {
-                    log.debug("Can't find driver " + driverId + " in datasource provider " + provider.getId() + " for datasource '" + id + "'. Create new driver");
-                    driver = provider.createDriver(driverId);
-                    driver.setName(driverId);
-                    driver.setDescription("Missing driver " + driverId);
-                    driver.setDriverClassName("java.sql.Driver");
-                    driver.setTemporary(true);
-                    provider.addDriver(driver);
+                while (substitutedDriver.getReplacedBy() != null) {
+                    substitutedDriver = substitutedDriver.getReplacedBy();
                 }
 
                 DataSourceDescriptor dataSource = registry.getDataSource(id);
@@ -544,7 +548,8 @@ class DataSourceSerializerModern implements DataSourceSerializer
                         configurationStorage.isVirtual() ? registry.getDefaultStorage() : configurationStorage,
                         origin,
                         id,
-                        driver,
+                        originalDriver,
+                        substitutedDriver,
                         new DBPConnectionConfiguration());
                 } else {
                     oldDataSource = new DataSourceDescriptor(dataSource, registry);
@@ -729,6 +734,52 @@ class DataSourceSerializerModern implements DataSourceSerializer
 
     }
 
+    @Nullable
+    private static DriverDescriptor parseDriver(
+        @NotNull String id,
+        @NotNull String providerId,
+        @NotNull String driverId,
+        boolean createIfAbsent
+    ) {
+        if (CommonUtils.isEmpty(providerId)) {
+            log.debug("Empty datasource provider for datasource '" + id + "'");
+            return null;
+        }
+
+        if (CommonUtils.isEmpty(driverId)) {
+            log.debug("Empty driver for datasource '" + id + "'");
+            return null;
+        }
+
+        DataSourceProviderDescriptor provider = DataSourceProviderRegistry.getInstance().getDataSourceProvider(providerId);
+        if (provider == null) {
+            if (createIfAbsent) {
+                log.debug("Can't find datasource provider " + providerId + " for datasource '" + id + "'");
+                provider = (DataSourceProviderDescriptor) DataSourceProviderRegistry.getInstance().makeFakeProvider(providerId);
+            } else {
+                return null;
+            }
+        }
+
+        DriverDescriptor driver = provider.getOriginalDriver(driverId);
+        if (driver == null) {
+            if (createIfAbsent) {
+                log.debug("Can't find driver " + driverId + " in datasource provider "
+                    + provider.getId() + " for datasource '" + id + "'. Create new driver");
+                driver = provider.createDriver(driverId);
+                driver.setName(driverId);
+                driver.setDescription("Missing driver " + driverId);
+                driver.setDriverClassName("java.sql.Driver");
+                driver.setTemporary(true);
+                provider.addDriver(driver);
+            } else {
+                return null;
+            }
+        }
+
+        return driver;
+    }
+
     private void deserializeModifyPermissions(Map<String, Object> conObject, DBPDataSourcePermissionOwner permissionOwner) {
         Map<String, Object> securityCfg = JSONUtils.getObject(conObject, "security");
         if (!CommonUtils.isEmpty(securityCfg)) {
@@ -833,6 +884,10 @@ class DataSourceSerializerModern implements DataSourceSerializer
         json.beginObject();
         JSONUtils.field(json, RegistryConstants.ATTR_PROVIDER, dataSource.getDriver().getProviderDescriptor().getId());
         JSONUtils.field(json, RegistryConstants.ATTR_DRIVER, dataSource.getDriver().getId());
+        if (dataSource.getDriver() != dataSource.getOriginalDriver()) {
+            JSONUtils.field(json, ATTR_ORIGINAL_PROVIDER, dataSource.getOriginalDriver().getProviderDescriptor().getId());
+            JSONUtils.field(json, ATTR_ORIGINAL_DRIVER, dataSource.getOriginalDriver().getId());
+        }
         DBPDataSourceOrigin origin = dataSource.getOriginSource();
         if (origin != DataSourceOriginLocal.INSTANCE) {
             Map<String, Object> originProps = new LinkedHashMap<>();