diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebConnectionConfigInputHandler.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebConnectionConfigInputHandler.java index 57614a98d0..e370ec4f27 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebConnectionConfigInputHandler.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebConnectionConfigInputHandler.java @@ -1,6 +1,6 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2024 DBeaver Corp and others + * Copyright (C) 2010-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.registry.DataSourceDescriptor; +import org.jkiss.dbeaver.registry.DataSourcePreferenceStore; import org.jkiss.utils.CommonUtils; public class WebConnectionConfigInputHandler { @@ -93,6 +94,9 @@ public void updateDataSource(@NotNull C dataSource) throws DBWebException { input.isSharedCredentials() ); dataSource.setConnectionReadOnly(input.isReadOnly()); + DataSourcePreferenceStore preferenceStore = dataSource.getPreferenceStore(); + preferenceStore.clear(); + preferenceStore.setProperties(input.getDefaultUserPreferences()); } @NotNull diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionConfig.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionConfig.java index 277e59c85d..fd1c39bfe5 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionConfig.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionConfig.java @@ -1,6 +1,6 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2024 DBeaver Corp and others + * Copyright (C) 2010-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.jkiss.dbeaver.model.meta.Property; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -64,6 +65,8 @@ public class WebConnectionConfig { private Boolean defaultAutoCommit; private String defaultCatalogName; private String defaultSchemaName; + @NotNull + private Map defaultUserPreferences = new LinkedHashMap<>(); public WebConnectionConfig() { } @@ -111,6 +114,8 @@ public WebConnectionConfig(@NotNull Map params) { String configType = JSONUtils.getString(params, "configurationType"); configurationType = configType == null ? null : DBPDriverConfigurationType.valueOf(configType); + Map stringObjectUserPrefMap = JSONUtils.getObject(params, "defaultUserPreferences"); + stringObjectUserPrefMap.forEach((key, value) -> defaultUserPreferences.put(key, value.toString())); networkHandlersConfig = new ArrayList<>(); for (Map nhc : JSONUtils.getObjectList(params, "networkHandlersConfig")) { networkHandlersConfig.add(new WebNetworkHandlerConfigInput(nhc)); @@ -367,4 +372,13 @@ public String getDefaultSchemaName() { public void setDefaultSchemaName(String defaultSchemaName) { this.defaultSchemaName = defaultSchemaName; } + + @NotNull + public Map getDefaultUserPreferences() { + return defaultUserPreferences; + } + + public void setDefaultUserPreferences(@NotNull Map defaultUserPreferences) { + this.defaultUserPreferences = defaultUserPreferences; + } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java index 4f2a42d8eb..9f4f1d6986 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/WebConnectionInfo.java @@ -40,11 +40,13 @@ import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; import org.jkiss.dbeaver.model.navigator.DBNDataSource; +import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; import org.jkiss.dbeaver.model.preferences.DBPPropertySource; import org.jkiss.dbeaver.model.rm.RMConstants; import org.jkiss.dbeaver.model.rm.RMProjectPermission; import org.jkiss.dbeaver.model.runtime.DBRRunnableParametrized; +import org.jkiss.dbeaver.registry.DataSourcePreferenceStore; import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor; import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry; import org.jkiss.dbeaver.runtime.DBWorkbench; @@ -293,6 +295,16 @@ public DBNBrowseSettings getDefaultNavigatorSettings() { return dataSourceContainer.getNavigatorSettings().getOriginalSettings(); } + @Property + @NotNull + public Map getDefaultUserPreferences() { + DBPPreferenceStore preferenceStore = dataSourceContainer.getPreferenceStore(); + if (preferenceStore instanceof DataSourcePreferenceStore dataSourcePreferenceStore) { + return dataSourcePreferenceStore.getProperties(); + } + return Collections.emptyMap(); + } + @Property @NotNull public List getSupportedDataFormats() { @@ -578,4 +590,5 @@ public List getTools() { public void setCredentialsSavedInSession(@Nullable Boolean credentialsSavedInSession) { this.credentialsSavedInSession = credentialsSavedInSession; } + } diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index ce41e5ec73..e5e7c35af2 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -565,6 +565,8 @@ type ConnectionInfo { requiredAuth: String defaultCatalogName: String @since(version: "25.0.5") defaultSchemaName: String @since(version: "25.0.5") + "Default user settings for connection" + defaultUserPreferences: Object @since(version: "26.0.2") "List of tools that can be used with this connection. Returns empty list if no tools are available" tools: [String!]! @since(version: "24.1.3") @@ -741,6 +743,8 @@ input ConnectionConfig { defaultCatalogName: String @since(version: "25.0.5") @deprecated(reason: "25.2.1 use expertPropertyValues instead") "Sets schema name for the connection" defaultSchemaName: String @since(version: "25.0.5") @deprecated(reason: "25.2.1 use expertPropertyValues instead") + "Default user settings for connection" + defaultUserPreferences: Object @since(version: "26.0.2") } #################################################### @@ -846,6 +850,7 @@ extend type Mutation { "Sets to default navigator settings for connection. Resets all user navigator settings for this connection." clearConnectionNavigatorSettings(projectId: ID!, id: ID!): ConnectionInfo! @since(version: "25.3.2") + setObjectSettingsForDatasource(id: ID!, projectId:ID, settings: Object!): Object! @since(version: "25.3.5") #### Generic async functions "Cancel async task by ID" diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java index 73a25dfe14..b8539a208e 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/DBWServiceCore.java @@ -1,6 +1,6 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2025 DBeaver Corp and others + * Copyright (C) 2010-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import jakarta.servlet.http.HttpServletResponse; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.rm.RMConstants; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.dbeaver.registry.settings.ProductSettingDescriptor; @@ -218,6 +219,14 @@ WebConnectionInfo clearConnectionNavigatorSettings( @NotNull String id ) throws DBWebException; + @NotNull + Map setObjectSettingsForDatasource( + @NotNull WebSession webSession, + @NotNull String projectId, + @NotNull String objectId, + @NotNull Map settings + ) throws DBException; + /////////////////////////////////////////// // Async tasks diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java index 6d652e610f..a8a81626ee 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java @@ -163,6 +163,12 @@ public void bindWiring(DBWBindingContext model) throws DBWebException { getArgumentVal(env, "id") ) ) + .dataFetcher("setObjectSettingsForDatasource", env -> getService(env).setObjectSettingsForDatasource( + getWebSession(env), + getProjectReference(env), + getArgumentVal(env, "id"), + getArgumentVal(env, "settings") + )) .dataFetcher("asyncTaskInfo", env -> getService(env).getAsyncTaskInfo( getWebSession(env), diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index d5704948ba..9c41c5ac47 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -1,6 +1,6 @@ /* * DBeaver - Universal Database Manager - * Copyright (C) 2010-2025 DBeaver Corp and others + * Copyright (C) 2010-2026 DBeaver Corp and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,12 +58,14 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.secret.DBSSecretController; import org.jkiss.dbeaver.model.secret.DBSSecretValue; +import org.jkiss.dbeaver.model.security.SMObjectType; import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettingsUtils; import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor; import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry; +import org.jkiss.dbeaver.registry.project.BaseProjectSettings; import org.jkiss.dbeaver.registry.settings.ProductSettingDescriptor; import org.jkiss.dbeaver.registry.settings.ProductSettingsRegistry; import org.jkiss.dbeaver.runtime.DBWorkbench; @@ -795,6 +797,25 @@ public WebConnectionInfo clearConnectionNavigatorSettings( return connectionInfo; } + @Override + @NotNull + public Map setObjectSettingsForDatasource( + @NotNull WebSession webSession, + @NotNull String projectId, + @NotNull String objectId, + @NotNull Map settings + ) throws DBException { + + WebSessionProjectImpl projectById = webSession.getProjectById(projectId); + if (projectById == null) { + throw new DBWebException("Project '" + projectId + "' not found"); + } + BaseProjectSettings projectSettings = projectById.getProjectSettings(); + projectSettings.setObjectSettings(SMObjectType.datasource, objectId, settings); + Map objectSettings = projectSettings.getObjectSettings(SMObjectType.datasource, objectId); + return objectSettings == null ? new HashMap<>() : objectSettings; + } + @Override public WebAsyncTaskInfo getAsyncTaskInfo(WebSession webSession, String taskId, Boolean removeOnFinish) throws DBWebException {