From f4b55add998b2ba2317892da032ff35c97d802a4 Mon Sep 17 00:00:00 2001 From: alex <48489896+devnaumov@users.noreply.github.com> Date: Thu, 20 Aug 2026 17:29:58 +0200 Subject: [PATCH] dbeaver/pro#9515 do not duplicate driver props fix (#4560) * dbeaver/pro#9515 do not duplicate driver props fix * dbeaver/pro#9515 pass default values * dbeaver/pro#9515 fix using mutable list * dbeaver/pro#9515 add comment --------- Co-authored-by: Ainur Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> Co-authored-by: Ainur <59531286+yagudin10@users.noreply.github.com> --- .../src/io/cloudbeaver/WebServiceUtils.java | 21 ++++++++----- .../src/PropertiesTable/PropertiesTable.tsx | 7 +++-- .../src/ConnectionInfoResource.ts | 9 +++++- .../ConnectionFormDriverPropertiesPart.ts | 30 ++++++++++++++++--- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index 87ff43dbcc..8c1cb33cf5 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -50,7 +50,6 @@ import org.jkiss.dbeaver.model.rm.RMProjectType; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.dbeaver.runtime.properties.PropertyCollector; import org.jkiss.dbeaver.runtime.properties.PropertySourceCustom; -import org.jkiss.utils.ArrayUtils; import org.jkiss.utils.CommonUtils; import java.io.InputStream; @@ -209,9 +208,16 @@ public class WebServiceUtils extends WebCommonUtils { dataSourceContainer, cfg ); - Map connectionProperties = driver.getConnectionProperties(); + List propertyList = new ArrayList<>(Arrays.asList(properties)); + Set propertyNames = propertyList.stream().map(DBPPropertyDescriptor::getId).collect(Collectors.toSet()); + Map connectionProperties = new LinkedHashMap<>(driver.getConnectionProperties()); + // In case of collision, value from connectionProperties will be used for a driver property. + // Default value of property will be from driver. for (Map.Entry connProp : connectionProperties.entrySet()) { String propName = connProp.getKey(); + if (propertyNames.contains(propName)) { + continue; + } Object propValue = connProp.getValue(); DBPPropertyDescriptor dbpPropertyDescriptor = new PropertyDescriptor( null, @@ -223,19 +229,20 @@ public class WebServiceUtils extends WebCommonUtils { propValue, null ); - properties = ArrayUtils.add(DBPPropertyDescriptor.class, properties, dbpPropertyDescriptor); + propertyList.add(dbpPropertyDescriptor); cfg.setProperty(propName, (String) propValue); } - if (properties == null) { + if (propertyList.isEmpty()) { return new WebPropertyInfo[0]; } + connectionProperties.putAll(cfg.getProperties()); PropertySourceCustom propertySource = new PropertySourceCustom( - properties, - cfg.getProperties() + propertyList, + connectionProperties ); - return Arrays.stream(properties) + return propertyList.stream() .map(p -> new WebPropertyInfo(webSession, p, propertySource)).toArray(WebPropertyInfo[]::new); } catch (DBException e) { log.error("Error reading driver properties:\n" + e.getMessage()); diff --git a/webapp/packages/core-blocks/src/PropertiesTable/PropertiesTable.tsx b/webapp/packages/core-blocks/src/PropertiesTable/PropertiesTable.tsx index 5254af391b..533470d5c3 100644 --- a/webapp/packages/core-blocks/src/PropertiesTable/PropertiesTable.tsx +++ b/webapp/packages/core-blocks/src/PropertiesTable/PropertiesTable.tsx @@ -7,7 +7,7 @@ */ import { computed } from 'mobx'; import { observer } from 'mobx-react-lite'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useDeferredValue, useMemo, useState } from 'react'; import { getObjectPropertyOptionValue } from '@cloudbeaver/core-sdk'; import { isNotNullDefined } from '@dbeaver/js-helpers'; @@ -47,6 +47,7 @@ export const PropertiesTable = observer(function PropertiesTable(props) { const style = useS(styles); const [filterValue, setFilterValue] = useState(''); + const deferredFilterValue = useDeferredValue(filterValue); const sortedProperties = useMemo( () => @@ -54,9 +55,9 @@ export const PropertiesTable = observer(function PropertiesTable(props) { ((propsRef.sortByName ?? true) ? propsRef.properties.slice().sort((a, b) => (a.displayName ?? '').localeCompare(b.displayName ?? '')) : propsRef.properties - ).filter(p => p.new || p.key.toLocaleLowerCase().includes(filterValue.toLocaleLowerCase())), + ).filter(p => p.new || p.key.toLocaleLowerCase().includes(deferredFilterValue.toLocaleLowerCase())), ), - [propsRef.properties, propsRef.sortByName, filterValue], + [propsRef.properties, propsRef.sortByName, deferredFilterValue], ); const changeName = useCallback((id: string, key: string) => { diff --git a/webapp/packages/core-connections/src/ConnectionInfoResource.ts b/webapp/packages/core-connections/src/ConnectionInfoResource.ts index 596b89e861..10e23a4a49 100644 --- a/webapp/packages/core-connections/src/ConnectionInfoResource.ts +++ b/webapp/packages/core-connections/src/ConnectionInfoResource.ts @@ -522,9 +522,16 @@ export class ConnectionInfoResource extends CachedMapResource { + const options = toJS(config); + /* + We should not pass properties here. If we do, the values in ObjectPropertyInfo will be taken from the properties in the config. + By deleting them, we always get the values that are actually saved on the server. + */ + delete options.properties; + const { properties } = await this.graphQLService.sdk.getConnectionDriverProperties({ projectId, - config, + config: options, }); return properties; diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts index 7a39b2341a..8ff2068a2f 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/DriverProperties/ConnectionFormDriverPropertiesPart.ts @@ -12,7 +12,7 @@ import type { IConnectionFormState } from '../IConnectionFormState.js'; import { runInAction, toJS } from 'mobx'; import type { ConnectionFormOptionsPart } from '../Options/ConnectionFormOptionsPart.js'; import type { schema } from '@cloudbeaver/core-utils'; -import { getObjectPropertyOptionValue } from '@cloudbeaver/core-sdk'; +import { getObjectPropertyDefaultValue, getObjectPropertyOptionValue, getObjectPropertyValue } from '@cloudbeaver/core-sdk'; import type { CONNECTION_PROPERTIES_SCHEMA } from '../CONNECTION_CONFIG_SCHEMA.js'; type ConnectionProperties = schema.infer; @@ -33,8 +33,9 @@ export class ConnectionFormDriverPropertiesPart extends FormPart { if (!this.optionsPart.connectionKey) { - this.setInitialState(getDefaultState()); + const defaults = await this.getDefaultConfig(); + this.setInitialState(defaults); return; } @@ -108,4 +110,24 @@ export class ConnectionFormDriverPropertiesPart extends FormPart