Skip to content

Commit

Permalink
CB-5197 create main connection fields dynamically (#2693)
Browse files Browse the repository at this point in the history
* CB-5238 add main properties for connections

* CB-5197 render main properties

* CB-5197 render main properties

* CB-5238 set default values to main properties

* CB-5197 fix(ci/cd): respect base and target branches

* CB-5238 fixes after review

* CB-5197 review fixes

* CB-5197 switch to new model

* CB-5238 fixes after review

* CB-5197 remove custom configuration type

* CB-5238 remove custom config type from gql schema

* CB-5197 do not check configuration type for creds

* CB-5197 make argument optional

* CB-5238 fix creating connection with url

* CB-5238 rename param

* CB-5238 rename param

* CB-5197 rename field

---------

Co-authored-by: naumov <[email protected]>
Co-authored-by: Alexey <[email protected]>
Co-authored-by: Evgenia Bezborodova <[email protected]>
  • Loading branch information
4 people authored Jul 1, 2024
1 parent 4433018 commit 49875e4
Show file tree
Hide file tree
Showing 21 changed files with 301 additions and 155 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/backend-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ jobs:
sudo chmod 777 ../
shell: bash

- name: Determine branches
id: determine-branch
run: |
echo "pr_branch=${{ github.head_ref }}" >> $GITHUB_ENV
echo "base_branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_ENV
- name: Clone dbeaver/dbeaver
id: clone-repo
run: |
git clone -b ${{ env.pr_branch }} https://github.com/dbeaver/dbeaver.git ../dbeaver || git clone -b ${{ env.base_branch }} https://github.com/dbeaver/dbeaver.git ../dbeaver
- name: Run build script
run: ./build-backend.sh
shell: bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,16 @@ public void fireCloseListeners() {
}
}

@Property
public Map<String, String> getMainPropertyValues() {
Map<String, String> mainProperties = new LinkedHashMap<>();
mainProperties.put(DBConstants.PROP_HOST, getHost());
mainProperties.put(DBConstants.PROP_PORT, getPort());
mainProperties.put(DBConstants.PROP_DATABASE, getDatabaseName());
mainProperties.put(DBConstants.PROP_SERVER, getServerName());
return mainProperties;
}

@Property
public Map<String, String> getProviderProperties() {
return dataSourceContainer.getConnectionConfiguration().getProviderProperties();
Expand Down
11 changes: 11 additions & 0 deletions server/bundles/io.cloudbeaver.server/schema/service.core.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ type DriverInfo {
enabled: Boolean!
requiresServerName: Boolean
requiresDatabaseName: Boolean
useCustomPage: Boolean! @since(version: "24.1.2") # if host, port, database, server name fields are custom

licenseRequired: Boolean
license: String
Expand All @@ -248,6 +249,10 @@ type DriverInfo {
# Driver parameters (map name->value)
driverParameters: Object!

# Main driver properties
# Contains info about main fields (host, port, database, server name)
mainProperties: [ObjectPropertyInfo!]! @since(version: "24.1.2")

# Additional driver provider properties
# These properties can be configured by user on main connection page
# to provide important connection settings
Expand Down Expand Up @@ -340,6 +345,8 @@ type ConnectionInfo {
databaseName: String
url: String

mainPropertyValues: Object @since(version: "24.1.2")

keepAliveInterval: Int!
autocommit: Boolean

Expand Down Expand Up @@ -499,6 +506,10 @@ input ConnectionConfig {
port: String
serverName: String
databaseName: String

# Host, port, serverName, databaseName are also stored in mainPropertyValues for custom pages
mainPropertyValues: Object @since(version: "24.1.2")

# Connection url jdbc:{driver}://{host}[:{port}]/[{database}]
url: String
# Properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
Expand Down Expand Up @@ -150,22 +151,7 @@ public static DBPDataSourceContainer createConnectionFromConfig(WebConnectionCon
}

public static void setConnectionConfiguration(DBPDriver driver, DBPConnectionConfiguration dsConfig, WebConnectionConfig config) {
if (!CommonUtils.isEmpty(config.getUrl())) {
dsConfig.setUrl(config.getUrl());
} else {
if (config.getHost() != null) {
dsConfig.setHostName(config.getHost());
}
if (config.getPort() != null) {
dsConfig.setHostPort(config.getPort());
}
if (config.getDatabaseName() != null) {
dsConfig.setDatabaseName(config.getDatabaseName());
}
if (config.getServerName() != null) {
dsConfig.setServerName(config.getServerName());
}
}
setMainProperties(dsConfig, config);
if (config.getProperties() != null) {
Map<String, String> newProps = new LinkedHashMap<>();
for (Map.Entry<String, Object> pe : config.getProperties().entrySet()) {
Expand Down Expand Up @@ -222,6 +208,37 @@ public static void setConnectionConfiguration(DBPDriver driver, DBPConnectionCon
}
}

private static void setMainProperties(DBPConnectionConfiguration dsConfig, WebConnectionConfig config) {
if (CommonUtils.isNotEmpty(config.getUrl())) {
dsConfig.setUrl(config.getUrl());
return;
}
if (config.getMainPropertyValues() != null) {
for (Map.Entry<String, Object> e : config.getMainPropertyValues().entrySet()) {
switch (e.getKey()) {
case DBConstants.PROP_HOST -> dsConfig.setHostName(CommonUtils.toString(e.getValue()));
case DBConstants.PROP_PORT -> dsConfig.setHostPort(CommonUtils.toString(e.getValue()));
case DBConstants.PROP_DATABASE -> dsConfig.setDatabaseName(CommonUtils.toString(e.getValue()));
case DBConstants.PROP_SERVER -> dsConfig.setServerName(CommonUtils.toString(e.getValue()));
default -> throw new IllegalStateException("Unexpected value: " + e.getKey());
}
}
return;
}
if (config.getHost() != null) {
dsConfig.setHostName(config.getHost());
}
if (config.getPort() != null) {
dsConfig.setHostPort(config.getPort());
}
if (config.getDatabaseName() != null) {
dsConfig.setDatabaseName(config.getDatabaseName());
}
if (config.getServerName() != null) {
dsConfig.setServerName(config.getServerName());
}
}

public static void saveAuthProperties(
@NotNull DBPDataSourceContainer dataSourceContainer,
@NotNull DBPConnectionConfiguration configuration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class WebConnectionConfig {
private Map<String, Object> credentials;
private boolean saveCredentials;
private boolean sharedCredentials;
private Map<String, Object> mainPropertyValues;
private Map<String, Object> providerProperties;
private List<WebNetworkHandlerConfigInput> networkHandlersConfig;
private DBPDriverConfigurationType configurationType;
Expand Down Expand Up @@ -102,6 +103,7 @@ public WebConnectionConfig(Map<String, Object> params) {
saveCredentials = JSONUtils.getBoolean(params, "saveCredentials");
sharedCredentials = JSONUtils.getBoolean(params, "sharedCredentials");

mainPropertyValues = JSONUtils.getObjectOrNull(params, "mainPropertyValues");
providerProperties = JSONUtils.getObjectOrNull(params, "providerProperties");

String configType = JSONUtils.getString(params, "configurationType");
Expand Down Expand Up @@ -227,6 +229,11 @@ public void setSaveCredentials(boolean saveCredentials) {
this.saveCredentials = saveCredentials;
}

@Property
public Map<String, Object> getMainPropertyValues() {
return mainPropertyValues;
}

@Property
public Map<String, Object> getProviderProperties() {
return providerProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
import org.jkiss.dbeaver.runtime.properties.PropertySourceCustom;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

/**
Expand Down Expand Up @@ -233,6 +235,22 @@ public String getDefaultAuthModel() {
return AuthModelDatabaseNative.ID;
}

@Property
public WebPropertyInfo[] getMainProperties() {
DBPPropertyDescriptor[] properties = driver.getMainPropertyDescriptors();
// set default values to main properties
Map<String, String> defaultValues = new LinkedHashMap<>();
defaultValues.put(DBConstants.PROP_HOST, getDefaultHost());
defaultValues.put(DBConstants.PROP_PORT, getDefaultPort());
defaultValues.put(DBConstants.PROP_DATABASE, getDefaultDatabase());
defaultValues.put(DBConstants.PROP_SERVER, getDefaultServer());
PropertySourceCustom propertySource = new PropertySourceCustom(properties, defaultValues);

return Arrays.stream(properties)
.map(p -> new WebPropertyInfo(webSession, p, propertySource))
.toArray(WebPropertyInfo[]::new);
}

@Property
public WebPropertyInfo[] getProviderProperties() {
return Arrays.stream(driver.getProviderPropertyDescriptors())
Expand Down Expand Up @@ -276,4 +294,9 @@ public WebDriverLibraryInfo[] getDriverLibraries() {
.map(dbpDriverLibrary -> new WebDriverLibraryInfo(webSession, dbpDriverLibrary))
.toArray(WebDriverLibraryInfo[]::new);
}

@Property
public boolean getUseCustomPage() {
return !ArrayUtils.isEmpty(driver.getMainPropertyDescriptors());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { observer } from 'mobx-react-lite';

import { getObjectPropertyType, type ObjectPropertyInfo, type ObjectPropertyType } from '@cloudbeaver/core-sdk';
import { getObjectPropertyType, getObjectPropertyValueType, type ObjectPropertyInfo, type ObjectPropertyType } from '@cloudbeaver/core-sdk';
import { removeMetadataFromDataURL } from '@cloudbeaver/core-utils';

import { FieldCheckbox } from '../../FormControls/Checkboxes/FieldCheckbox';
Expand Down Expand Up @@ -70,7 +70,8 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
const translate = useTranslate();

const controlType = getObjectPropertyType(property);
const password = property.features.includes('password');
const type = getObjectPropertyValueType(property);
const isPassword = type === 'password';
const required = property.required && !readOnly;

const value = getValue(property.value, controlType);
Expand Down Expand Up @@ -172,7 +173,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
);
}

const passwordSaved = showRememberTip && ((password && !!property.value) || saved);
const passwordSaved = showRememberTip && ((isPassword && !!property.value) || saved);
const passwordSavedMessage = passwordSaved ? translate('core_blocks_object_property_info_password_saved') : undefined;

if (controlType === 'file' && state) {
Expand Down Expand Up @@ -233,8 +234,8 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
return (
<InputField
required={required}
type={password ? 'password' : 'text'}
title={password ? property.description || property.displayName : undefined}
type={type}
title={isPassword ? property.description || property.displayName : undefined}
labelTooltip={property.description || property.displayName}
name={property.id!}
state={state}
Expand All @@ -257,8 +258,8 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
return (
<InputField
required={required}
type={password ? 'password' : 'text'}
title={password ? property.description || property.displayName : undefined}
type={type}
title={isPassword ? property.description || property.displayName : undefined}
labelTooltip={property.description || property.displayName}
name={property.id!}
value={value}
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-connections/src/DBDriverResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class DBDriverResource extends CachedMapResource<string, DBDriver, DBDriv
includeDriverLibraries: false,
includeDriverParameters: false,
includeDriverProperties: false,
includeMainProperties: false,
includeProviderProperties: false,
};
}
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-sdk/src/getObjectPropertyType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import type { ObjectPropertyInfo } from './sdk';

export type ObjectPropertyType = 'checkbox' | 'selector' | 'link' | 'input' | 'textarea' | 'file';
export type ObjectPropertyType = 'checkbox' | 'selector' | 'link' | 'textarea' | 'file' | 'input';

export function getObjectPropertyType(property: ObjectPropertyInfo): ObjectPropertyType {
const dataType = property.dataType?.toLowerCase();
Expand Down
24 changes: 24 additions & 0 deletions webapp/packages/core-sdk/src/getObjectPropertyValueType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { ObjectPropertyInfo } from './sdk';

export type ObjectPropertyValueType = 'password' | 'text' | 'number';

export function getObjectPropertyValueType(property: ObjectPropertyInfo): ObjectPropertyValueType | undefined {
const dataType = property.dataType?.toLowerCase();

if (property.features.includes('password')) {
return 'password';
}

if (dataType === 'integer') {
return 'number';
}

return dataType === 'string' ? 'text' : undefined;
}
1 change: 1 addition & 0 deletions webapp/packages/core-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from './EnvironmentService';
export * from './EServerErrorCode';
export * from './getGQLResponse';
export * from './getObjectPropertyType';
export * from './getObjectPropertyValueType';
export * from './GQLError';
export * from './GQLErrorCatcher';
export * from './GraphQLService';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
query driverList($driverId: ID, $includeProviderProperties: Boolean!, $includeDriverProperties: Boolean!, $includeDriverParameters: Boolean!, $includeDriverLibraries: Boolean!) {
query driverList(
$driverId: ID
$includeProviderProperties: Boolean!
$includeMainProperties: Boolean!
$includeDriverProperties: Boolean!
$includeDriverParameters: Boolean!
$includeDriverLibraries: Boolean!
) {
drivers: driverList(id: $driverId) {
...DatabaseDriver
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ fragment DatabaseConnection on ConnectionInfo {
folder
nodePath

mainPropertyValues

configurationType @include(if: $customIncludeOptions)
useUrl @include(if: $customIncludeOptions)
host @include(if: $customIncludeOptions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fragment DatabaseDriver on DriverInfo {
embedded
enabled
requiresServerName
useCustomPage
anonymousAccess
promotedScore
providerId
Expand All @@ -22,8 +23,12 @@ fragment DatabaseDriver on DriverInfo {
applicableNetworkHandlers
configurationTypes

mainProperties @include(if: $includeMainProperties) {
...DriverPropertyInfo
}

providerProperties @include(if: $includeProviderProperties) {
...DriverProviderPropertyInfo
...DriverPropertyInfo
}

driverProperties @include(if: $includeDriverProperties) {
Expand All @@ -42,4 +47,4 @@ fragment DatabaseDriver on DriverInfo {
name
icon
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fragment DriverPropertyInfo on ObjectPropertyInfo {
...ObjectPropertyInfo
supportedConfigurationTypes
}

This file was deleted.

Loading

0 comments on commit 49875e4

Please sign in to comment.