diff --git a/.docs/changelog.md b/.docs/changelog.md index 469142d4f9393e920b732fd3d9caa0f13ac3dec5..7f0c6df0028df5ff879ec0efb43ae12e8d460e3a 100644 --- a/.docs/changelog.md +++ b/.docs/changelog.md @@ -41,6 +41,8 @@ author: Martin Weise * Replaced sequential numerical ids with non-guessable random ids in the Metadata Database in [#491](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/491). +* Changed the interface for executing query in subsets/views + in [#493](https://gitlab.phaidra.org/fair-data-austria-db-repository/fda-services/-/issues/493). #### Removals diff --git a/dbrepo-auth-service/dbrepo-realm.json b/dbrepo-auth-service/dbrepo-realm.json index cd8d8a0e140b4745553e11dabbedcfe8c234b10a..9c6049095c2501876c686b3d03a5f3f92c42017d 100644 --- a/dbrepo-auth-service/dbrepo-realm.json +++ b/dbrepo-auth-service/dbrepo-realm.json @@ -42,7 +42,7 @@ "maxFailureWaitSeconds" : 900, "minimumQuickLoginWaitSeconds" : 60, "waitIncrementSeconds" : 60, - "quickLoginCheckMilliSeconds" : 5000, + "quickLoginCheckMilliSeconds" : 1, "maxDeltaTimeSeconds" : 1036800, "failureFactor" : 10, "roles" : { @@ -2429,7 +2429,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-address-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "saml-user-property-mapper" ] } }, { "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", @@ -2455,7 +2455,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "saml-user-attribute-mapper", "saml-user-property-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper" ] } } ], "org.keycloak.userprofile.UserProfileProvider" : [ { @@ -2479,8 +2479,8 @@ "config" : { "ldap.attribute" : [ "createTimestamp" ], "is.mandatory.in.ldap" : [ "false" ], - "read.only" : [ "true" ], "always.read.value.from.ldap" : [ "true" ], + "read.only" : [ "true" ], "user.model.attribute" : [ "createTimestamp" ] } }, { @@ -2491,8 +2491,8 @@ "config" : { "ldap.attribute" : [ "sn" ], "is.mandatory.in.ldap" : [ "true" ], - "always.read.value.from.ldap" : [ "true" ], "read.only" : [ "false" ], + "always.read.value.from.ldap" : [ "true" ], "user.model.attribute" : [ "lastName" ] } }, { @@ -2530,9 +2530,9 @@ "user.roles.retrieve.strategy" : [ "LOAD_GROUPS_BY_MEMBER_ATTRIBUTE" ], "group.name.ldap.attribute" : [ "cn" ], "membership.ldap.attribute" : [ "member" ], + "ignore.missing.groups" : [ "false" ], "preserve.group.inheritance" : [ "false" ], "membership.user.ldap.attribute" : [ "uid" ], - "ignore.missing.groups" : [ "false" ], "memberof.ldap.attribute" : [ "memberOf" ], "group.object.classes" : [ "groupOfNames" ], "groups.dn" : [ "ou=users,dc=dbrepo,dc=at" ], @@ -2558,18 +2558,18 @@ "subComponents" : { }, "config" : { "ldap.attribute" : [ "uid" ], - "is.mandatory.in.ldap" : [ "true" ], "attribute.force.default" : [ "false" ], + "is.mandatory.in.ldap" : [ "true" ], "is.binary.attribute" : [ "false" ], - "read.only" : [ "false" ], "always.read.value.from.ldap" : [ "false" ], + "read.only" : [ "false" ], "user.model.attribute" : [ "username" ] } } ] }, "config" : { - "fullSyncPeriod" : [ "-1" ], "pagination" : [ "false" ], + "fullSyncPeriod" : [ "-1" ], "startTls" : [ "false" ], "connectionPooling" : [ "true" ], "usersDn" : [ "ou=users,dc=dbrepo,dc=at" ], @@ -2577,15 +2577,15 @@ "useKerberosForPasswordAuthentication" : [ "false" ], "importEnabled" : [ "true" ], "enabled" : [ "true" ], - "bindDn" : [ "cn=admin,dc=dbrepo,dc=at" ], "bindCredential" : [ "admin" ], - "changedSyncPeriod" : [ "-1" ], + "bindDn" : [ "cn=admin,dc=dbrepo,dc=at" ], "usernameLDAPAttribute" : [ "uid" ], + "changedSyncPeriod" : [ "-1" ], "lastSync" : [ "1719252666" ], "vendor" : [ "other" ], "uuidLDAPAttribute" : [ "entryUUID" ], - "allowKerberosAuthentication" : [ "false" ], "connectionUrl" : [ "ldap://identity-service:1389" ], + "allowKerberosAuthentication" : [ "false" ], "syncRegistrations" : [ "true" ], "authType" : [ "simple" ], "useTruststoreSpi" : [ "always" ], diff --git a/dbrepo-auth-service/listeners/target/create-event-listener.jar b/dbrepo-auth-service/listeners/target/create-event-listener.jar index 087747d1bce60c75c887a495e51d8b94617624f1..fdbd461988b553d11d6b24e64d63e9689e20bad0 100644 Binary files a/dbrepo-auth-service/listeners/target/create-event-listener.jar and b/dbrepo-auth-service/listeners/target/create-event-listener.jar differ diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java index e64deaa758a2a20100671b4526d7bacd609f3a86..4ca4810f770651d39351f039ecd8588562a0fd16 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/SubsetEndpoint.java @@ -9,9 +9,13 @@ import at.tuwien.api.database.query.QueryPersistDto; import at.tuwien.api.database.query.SubsetDto; import at.tuwien.api.error.ApiErrorDto; import at.tuwien.exception.*; +import at.tuwien.gateway.MetadataServiceGateway; import at.tuwien.mapper.MariaDbMapper; import at.tuwien.mapper.MetadataMapper; -import at.tuwien.service.*; +import at.tuwien.service.CacheService; +import at.tuwien.service.DatabaseService; +import at.tuwien.service.StorageService; +import at.tuwien.service.SubsetService; import at.tuwien.validation.EndpointValidator; import io.micrometer.observation.annotation.Observed; import io.swagger.v3.oas.annotations.Operation; @@ -53,23 +57,23 @@ public class SubsetEndpoint extends RestEndpoint { private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; private final MetadataMapper metadataMapper; - private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; private final EndpointValidator endpointValidator; + private final MetadataServiceGateway metadataServiceGateway; @Autowired - public SubsetEndpoint(CacheService cacheService, MariaDbMapper mariaDbMapper, SubsetService subsetService, - MetadataMapper metadataMapper, MetricsService metricsService, StorageService storageService, - DatabaseService databaseService, EndpointValidator endpointValidator) { + public SubsetEndpoint(CacheService cacheService, MariaDbMapper mariaDbMapper, SubsetService subsetService, + MetadataMapper metadataMapper, StorageService storageService, DatabaseService databaseService, + EndpointValidator endpointValidator, MetadataServiceGateway metadataServiceGateway) { this.cacheService = cacheService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; this.metadataMapper = metadataMapper; - this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; this.endpointValidator = endpointValidator; + this.metadataServiceGateway = metadataServiceGateway; } @GetMapping @@ -192,7 +196,6 @@ public class SubsetEndpoint extends RestEndpoint { log.trace("accept header matches csv"); final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, null, null); final Dataset<Row> dataset = subsetService.getData(database, query); - metricsService.countSubsetGetData(databaseId, subsetId); final ExportResourceDto resource = storageService.transformDataset(dataset); final HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); @@ -377,9 +380,9 @@ public class SubsetEndpoint extends RestEndpoint { .headers(headers) .build(); } + subset.setIdentifiers(metadataServiceGateway.getIdentifiers(database.getId(), subset.getId())); final String query = mariaDbMapper.rawSelectQuery(subset.getQuery(), timestamp, page, size); final Dataset<Row> dataset = subsetService.getData(database, query); - metricsService.countSubsetGetData(databaseId, subsetId); final String viewName = metadataMapper.queryDtoToViewName(subset); databaseService.createView(database, viewName, subset.getQuery()); final ViewDto view = databaseService.inspectView(database, viewName); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java index ab306ea6081163f17c3b36878b8fee36609b2036..6914726cb84a886d97210dce9f1f60ac19db53b5 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/TableEndpoint.java @@ -53,7 +53,6 @@ public class TableEndpoint extends RestEndpoint { private final TableService tableService; private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; - private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; private final EndpointValidator endpointValidator; @@ -61,14 +60,12 @@ public class TableEndpoint extends RestEndpoint { @Autowired public TableEndpoint(CacheService cacheService, TableService tableService, MariaDbMapper mariaDbMapper, - SubsetService subsetService, MetricsService metricsService, StorageService storageService, - DatabaseService databaseService, EndpointValidator endpointValidator, - MetadataServiceGateway metadataServiceGateway) { + SubsetService subsetService, StorageService storageService, DatabaseService databaseService, + EndpointValidator endpointValidator, MetadataServiceGateway metadataServiceGateway) { this.cacheService = cacheService; this.tableService = tableService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; - this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; this.endpointValidator = endpointValidator; @@ -301,7 +298,6 @@ public class TableEndpoint extends RestEndpoint { final String query = mariaDbMapper.defaultRawSelectQuery(database.getInternalName(), table.getInternalName(), timestamp, page, size); final Dataset<Row> dataset = subsetService.getData(database, query); - metricsService.countTableGetData(databaseId, tableId); return ResponseEntity.ok() .headers(headers) .body(transform(dataset)); @@ -647,7 +643,6 @@ public class TableEndpoint extends RestEndpoint { table.getInternalName(), timestamp, null, null); final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(table.getDatabaseId()), query); - metricsService.countTableGetData(databaseId, tableId); final ExportResourceDto resource = storageService.transformDataset(dataset); final HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); diff --git a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 430ac4edc5e00aa2a65a22ce8a07fb2a909bf486..5c1fdb57dbc30b428d104e4c145f4a0064105f78 100644 --- a/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-data-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -49,20 +49,18 @@ public class ViewEndpoint extends RestEndpoint { private final CacheService cacheService; private final MariaDbMapper mariaDbMapper; private final SubsetService subsetService; - private final MetricsService metricsService; private final StorageService storageService; private final DatabaseService databaseService; private final EndpointValidator endpointValidator; @Autowired public ViewEndpoint(ViewService viewService, CacheService cacheService, MariaDbMapper mariaDbMapper, - SubsetService subsetService, MetricsService metricsService, StorageService storageService, - DatabaseService databaseService, EndpointValidator endpointValidator) { + SubsetService subsetService, StorageService storageService, DatabaseService databaseService, + EndpointValidator endpointValidator) { this.viewService = viewService; this.cacheService = cacheService; this.mariaDbMapper = mariaDbMapper; this.subsetService = subsetService; - this.metricsService = metricsService; this.storageService = storageService; this.databaseService = databaseService; this.endpointValidator = endpointValidator; @@ -303,7 +301,6 @@ public class ViewEndpoint extends RestEndpoint { view.getInternalName(), timestamp, page, size); final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId), query); - metricsService.countViewGetData(databaseId, viewId); return ResponseEntity.ok() .headers(headers) .body(transform(dataset)); @@ -371,7 +368,6 @@ public class ViewEndpoint extends RestEndpoint { view.getInternalName(), timestamp, null, null); final Dataset<Row> dataset = subsetService.getData(cacheService.getDatabase(databaseId), query); - metricsService.countViewGetData(databaseId, viewId); final ExportResourceDto resource = storageService.transformDataset(dataset); final HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\""); diff --git a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java index d5bfaa1bbb56ace796babe4e9cb17d0098298bfe..d05979af36b59882a76078bb424aa3e43230933f 100644 --- a/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java +++ b/dbrepo-data-service/rest-service/src/test/java/at/tuwien/service/SubsetServiceIntegrationTest.java @@ -1,6 +1,6 @@ package at.tuwien.service; -import at.tuwien.api.database.query.QueryDto; +import at.tuwien.api.database.query.*; import at.tuwien.api.identifier.IdentifierBriefDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; @@ -13,6 +13,9 @@ import org.apache.spark.sql.Row; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -25,7 +28,9 @@ import java.sql.SQLException; import java.time.Instant; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.UUID; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.when; @@ -42,6 +47,14 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { @MockBean private MetadataServiceGateway metadataServiceGateway; + public static Stream<Arguments> create_arguments() { + return Stream.of( + Arguments.arguments("singleQuote", "' DROP TABLE `weather_location`; --"), + Arguments.arguments("singleQuoteEscaped", "\' DROP TABLE `weather_location`; --"), + Arguments.arguments("doubleQuote", "\" DROP TABLE `weather_location`; --") + ); + } + @Container private static MariaDBContainer<?> mariaDBContainer = MariaDbContainerConfig.getContainer(); @@ -227,6 +240,40 @@ public class SubsetServiceIntegrationTest extends AbstractUnitTest { assertNotNull(response); } + @Test + public void create_succeeds() throws SQLException, QueryStoreInsertException, ViewMalformedException, + TableNotFoundException, QueryMalformedException, ImageNotFoundException { + + /* test */ + final UUID response = subsetService.create(DATABASE_1_PRIVILEGED_DTO, QUERY_1_SUBSET_DTO, QUERY_1_CREATED, USER_1_ID); + assertNotNull(response); + } + + @ParameterizedTest + @MethodSource("create_arguments") + public void create_illegalQuery_succeeds(String name, String injection) throws TableNotFoundException, + QueryStoreInsertException, ViewMalformedException, SQLException, QueryMalformedException, + ImageNotFoundException { + final SubsetDto request = SubsetDto.builder() + .tableId(TABLE_1_ID) + .columns(new LinkedList<>(List.of(COLUMN_1_1_ID, COLUMN_1_2_ID, COLUMN_1_3_ID, COLUMN_1_4_ID, COLUMN_1_5_ID))) + .filter(new LinkedList<>(List.of(FilterDto.builder() + .type(FilterTypeDto.WHERE) + .columnId(COLUMN_1_1_ID) + .operatorId(IMAGE_1_OPERATORS_2_ID) + .value(injection) + .build()))) + .order(new LinkedList<>(List.of(OrderDto.builder() + .columnId(COLUMN_1_1_ID) + .direction(OrderTypeDto.ASC) + .build()))) + .build(); + + /* test */ + subsetService.create(DATABASE_1_PRIVILEGED_DTO, request, QUERY_1_CREATED, USER_1_ID); + assertEquals(1, MariaDbConfig.selectQuery(DATABASE_1_PRIVILEGED_DTO, "SELECT 1 WHERE EXISTS (SELECT * FROM `weather_location`)", Set.of()).size()); + } + @Test public void storeQuery_fails() { diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java index 7b28a9b2ed9297aa6bf775b172d5803f667ad663..66d8219c2a7205d0e320b7b22c07b8a90d284e2f 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java @@ -21,7 +21,6 @@ import at.tuwien.utils.MariaDbUtil; import org.jooq.Record; import org.jooq.*; import org.jooq.conf.ParamType; -import org.jooq.conf.StatementType; import org.mapstruct.Mapper; import org.mapstruct.Named; diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/MetricsService.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/MetricsService.java deleted file mode 100644 index 2beed4b773fea686aa3b9262e063acca82863667..0000000000000000000000000000000000000000 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/MetricsService.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.tuwien.service; - -import java.util.UUID; - -public interface MetricsService { - - void countTableGetData(UUID databaseId, UUID tableId); - - void countSubsetGetData(UUID databaseId, UUID subsetId); - - void countViewGetData(UUID databaseId, UUID viewId); -} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/MetricsServicePrometheusImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/MetricsServicePrometheusImpl.java deleted file mode 100644 index 0b49804c31a8b486ccbc3878220776726909bea2..0000000000000000000000000000000000000000 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/MetricsServicePrometheusImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package at.tuwien.service.impl; - -import at.tuwien.config.MetricsConfig; -import at.tuwien.mapper.MetadataMapper; -import at.tuwien.service.MetricsService; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Metrics; -import lombok.extern.log4j.Log4j2; -import org.springframework.stereotype.Service; - -import java.util.UUID; - -@Log4j2 -@Service -public class MetricsServicePrometheusImpl implements MetricsService { - - private final MetricsConfig metricsConfig; - private final MetadataMapper metadataMapper; - - public MetricsServicePrometheusImpl(MetricsConfig metricsConfig, MetadataMapper metadataMapper) { - this.metricsConfig = metricsConfig; - this.metadataMapper = metadataMapper; - } - - @Override - public void countTableGetData(UUID databaseId, UUID tableId) { - countGetData(databaseId, tableId, null, null); - } - - @Override - public void countSubsetGetData(UUID databaseId, UUID subsetId) { - countGetData(databaseId, null, subsetId, null); - } - - @Override - public void countViewGetData(UUID databaseId, UUID viewId) { - countGetData(databaseId, null, null, viewId); - } - - public void countGetData(UUID databaseId, UUID tableId, UUID subsetId, UUID viewId) { - Counter.builder("dbrepo.datasource.data.get") - .tag("uri", metadataMapper.metricToUri(metricsConfig.getBaseUrl(), databaseId, tableId, subsetId, viewId)) - .tag("protocol", "http") - .description("The total number of accessed data sources") - .register(Metrics.globalRegistry) - .increment(); - } - -} diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java index 869f12bde2b6182d4ca1504a76d33019a55d6c97..a2b70ece8623d321683aaa73b6bd29dd8e7b524b 100644 --- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java +++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/SubsetServiceMariaDbImpl.java @@ -131,8 +131,8 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer } @Override - public QueryDto findById(DatabaseDto database, UUID queryId) throws QueryNotFoundException, SQLException, - RemoteUnavailableException, DatabaseNotFoundException, MetadataServiceException { + public QueryDto findById(DatabaseDto database, UUID queryId) throws QueryNotFoundException, + SQLException, RemoteUnavailableException, DatabaseNotFoundException, MetadataServiceException { final ComboPooledDataSource dataSource = getDataSource(database); final Connection connection = dataSource.getConnection(); try { @@ -145,7 +145,6 @@ public class SubsetServiceMariaDbImpl extends DataConnector implements SubsetSer throw new QueryNotFoundException("Failed to find query"); } final QueryDto query = dataMapper.resultSetToQueryDto(resultSet); - query.setIdentifiers(metadataServiceGateway.getIdentifiers(database.getId(), queryId)); query.setOwner(database.getOwner()); query.setDatabaseId(database.getId()); return query; diff --git a/dbrepo-metadata-db/1_setup-schema.sql b/dbrepo-metadata-db/1_setup-schema.sql index 12e0f02a169c969ea0036652dc2198b79e492ebf..7e7978cad83580c330a28ef03ce3fd84623ee01e 100644 --- a/dbrepo-metadata-db/1_setup-schema.sql +++ b/dbrepo-metadata-db/1_setup-schema.sql @@ -538,30 +538,30 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'BIGINT(size)', 'bigint', 0, nul FALSE, null, null, null, 'https://mariadb.com/kb/en/decimal/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'DOUBLE(size, d)', 'double', null, null, null, FALSE, null, null, null, null, FALSE, null, null, null, 'https://mariadb.com/kb/en/double/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ENUM(v1,v2,...)', 'ENUM', null, null, null, null, null, null, null, - null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/ENUM/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ENUM(v1,v2,...)', 'enum', null, null, null, null, null, null, null, + null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/enum/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'FLOAT(size)', 'float', null, null, null, FALSE, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/float/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'INT(size)', 'int', null, null, null, FALSE, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/int/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGBLOB', 'longblob', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longblob/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGTEXT', 'longTEXT', null, null, null, null, null, null, null, null, - null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGTEXT', 'longtext', null, null, null, null, null, null, null, null, + null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longtext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMBLOB', 'mediumblob', null, null, null, null, null, null, null, null, null, null, 'max. 15.999 MiB', null, 'https://mariadb.com/kb/en/mediumblob/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMINT', 'mediumint', null, null, null, null, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMTEXT', 'mediumTEXT', null, null, null, null, null, null, null, - null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMTEXT', 'mediumtext', null, null, null, null, null, null, null, + null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumtext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SERIAL', 'serial', null, null, null, null, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/bigint/', TRUE, TRUE, TRUE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SET(v1,v2,...)', 'set', null, null, null, null, null, null, null, null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/set/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SMALLINT(size)', 'smallint', 0, null, null, FALSE, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/smallint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TEXT(size)', 'TEXT', 0, null, null, FALSE, null, null, null, null, - null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/TEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TEXT(size)', 'text', 0, null, null, FALSE, null, null, null, null, + null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/text/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TIME(fsp)', 'time', 0, 6, 0, FALSE, null, null, null, null, null, null, 'fsp=microsecond precision, min. 0, max. 6', 'e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S', 'https://mariadb.com/kb/en/time/', TRUE, TRUE, FALSE), @@ -574,14 +574,14 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'BIGINT(size)', 'bigint', 0, nul TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYINT(size)', 'tinyint', 0, null, null, FALSE, null, null, null, null, null, null, null, 'size in Bytes', 'https://mariadb.com/kb/en/tinyint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYTEXT', 'tinyTEXT', null, null, null, null, null, null, null, null, - null, null, null, 'max. 255 characters', 'https://mariadb.com/kb/en/tinyTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYTEXT', 'tinytext', null, null, null, null, null, null, null, null, + null, null, null, 'max. 255 characters', 'https://mariadb.com/kb/en/tinytext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'YEAR', 'year', 2, 4, null, FALSE, 2, null, null, null, null, null, 'min. 1901, max. 2155', 'e.g. YYYY, YY', 'https://mariadb.com/kb/en/year/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARBINARY(size)', 'varbinary', 0, null, null, TRUE, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/varbinary/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARCHAR(size)', 'VARCHAR', 0, 65532, 255, TRUE, null, null, null, null, - null, null, null, null, 'https://mariadb.com/kb/en/VARCHAR/', FALSE, TRUE, FALSE); + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARCHAR(size)', 'varchar', 0, 65532, 255, TRUE, null, null, null, null, + null, null, null, null, 'https://mariadb.com/kb/en/varchar/', FALSE, TRUE, FALSE); INSERT INTO `mdb_image_operators` (image_id, display_name, value, documentation) diff --git a/dbrepo-ui/bun.lockb b/dbrepo-ui/bun.lockb index 7ee1d3897245ee94212d8bfb6a6b97556b64f1d2..a4bc73dcd16c8e4a59a34fd431a7acf3a20627fa 100755 Binary files a/dbrepo-ui/bun.lockb and b/dbrepo-ui/bun.lockb differ diff --git a/dbrepo-ui/components/table/TableSchema.vue b/dbrepo-ui/components/table/TableSchema.vue index 811efae792d9bb2dd82b542d23ee1949558ac034..62d88647e4c1ee39a51be16ef2e6f50a6c739e86 100644 --- a/dbrepo-ui/components/table/TableSchema.vue +++ b/dbrepo-ui/components/table/TableSchema.vue @@ -42,6 +42,7 @@ item-title="display_name" item-value="value" required + :disabled="loadingColumnTypes" :rules="[v => !!v || $t('validation.required')]" persistent-hint :variant="inputVariant" @@ -264,7 +265,7 @@ export default { }, methods: { fetchColumnTypes () { - if (!this.database) { + if (!this.database || this.columnTypes.length > 0) { return } this.loadingColumnTypes = true @@ -287,6 +288,9 @@ export default { } toast.error(this.$t(code)) }) + .finally(() => { + this.loadingColumnTypes = false + }) }, shift (column) { if (!this.columns || this.columns.length === 0) { diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue index a2498d799b2ea0ee2ceb8649f4eee7101ad759a8..56db5fdc374cdfd683eb00328f86534cd9fd81bf 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/dataset.vue @@ -312,6 +312,8 @@ export default { } this.tableCreate.is_public = this.database.is_public this.tableCreate.is_schema_public = this.database.is_schema_public + /* fetch types in advance */ + this.$refs.schema.fetchColumnTypes() }, computed: { database() { diff --git a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue index 1c48d143ca83eafeaa6ed21eac3ee9b3190e94aa..b05e8c0b98e5f5baa3f931cbb46e5f5e3fc69c11 100644 --- a/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue +++ b/dbrepo-ui/pages/database/[database_id]/table/create/schema.vue @@ -132,6 +132,7 @@ direction="vertical"> <v-container> <TableSchema + ref="schema" submit-text="Create" :disabled="!valid || table" :columns="tableCreate.columns" @@ -302,6 +303,8 @@ export default { } this.tableCreate.is_public = this.database.is_public this.tableCreate.is_schema_public = this.database.is_schema_public + /* fetch types in advance */ + this.$refs.schema.fetchColumnTypes() }, methods: { notEmpty, diff --git a/helm/dbrepo/files/01-setup-schema.sql b/helm/dbrepo/files/01-setup-schema.sql index 12e0f02a169c969ea0036652dc2198b79e492ebf..7e7978cad83580c330a28ef03ce3fd84623ee01e 100644 --- a/helm/dbrepo/files/01-setup-schema.sql +++ b/helm/dbrepo/files/01-setup-schema.sql @@ -538,30 +538,30 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'BIGINT(size)', 'bigint', 0, nul FALSE, null, null, null, 'https://mariadb.com/kb/en/decimal/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'DOUBLE(size, d)', 'double', null, null, null, FALSE, null, null, null, null, FALSE, null, null, null, 'https://mariadb.com/kb/en/double/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ENUM(v1,v2,...)', 'ENUM', null, null, null, null, null, null, null, - null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/ENUM/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'ENUM(v1,v2,...)', 'enum', null, null, null, null, null, null, null, + null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/enum/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'FLOAT(size)', 'float', null, null, null, FALSE, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/float/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'INT(size)', 'int', null, null, null, FALSE, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/int/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGBLOB', 'longblob', null, null, null, null, null, null, null, null, null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longblob/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGTEXT', 'longTEXT', null, null, null, null, null, null, null, null, - null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'LONGTEXT', 'longtext', null, null, null, null, null, null, null, null, + null, null, 'max. 3.999 GiB', null, 'https://mariadb.com/kb/en/longtext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMBLOB', 'mediumblob', null, null, null, null, null, null, null, null, null, null, 'max. 15.999 MiB', null, 'https://mariadb.com/kb/en/mediumblob/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMINT', 'mediumint', null, null, null, null, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMTEXT', 'mediumTEXT', null, null, null, null, null, null, null, - null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'MEDIUMTEXT', 'mediumtext', null, null, null, null, null, null, null, + null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/mediumtext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SERIAL', 'serial', null, null, null, null, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/bigint/', TRUE, TRUE, TRUE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SET(v1,v2,...)', 'set', null, null, null, null, null, null, null, null, null, null, null, 'e.g. value1, value2, ...', 'https://mariadb.com/kb/en/set/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'SMALLINT(size)', 'smallint', 0, null, null, FALSE, null, null, null, null, null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/smallint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TEXT(size)', 'TEXT', 0, null, null, FALSE, null, null, null, null, - null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/TEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TEXT(size)', 'text', 0, null, null, FALSE, null, null, null, null, + null, null, 'size in Bytes', null, 'https://mariadb.com/kb/en/text/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TIME(fsp)', 'time', 0, 6, 0, FALSE, null, null, null, null, null, null, 'fsp=microsecond precision, min. 0, max. 6', 'e.g. HH:MM:SS, HH:MM, HHMMSS, H:M:S', 'https://mariadb.com/kb/en/time/', TRUE, TRUE, FALSE), @@ -574,14 +574,14 @@ VALUES ('d79cb089-363c-488b-9717-649e44d8fcc5', 'BIGINT(size)', 'bigint', 0, nul TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYINT(size)', 'tinyint', 0, null, null, FALSE, null, null, null, null, null, null, null, 'size in Bytes', 'https://mariadb.com/kb/en/tinyint/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYTEXT', 'tinyTEXT', null, null, null, null, null, null, null, null, - null, null, null, 'max. 255 characters', 'https://mariadb.com/kb/en/tinyTEXT/', TRUE, TRUE, FALSE), + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'TINYTEXT', 'tinytext', null, null, null, null, null, null, null, null, + null, null, null, 'max. 255 characters', 'https://mariadb.com/kb/en/tinytext/', TRUE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'YEAR', 'year', 2, 4, null, FALSE, 2, null, null, null, null, null, 'min. 1901, max. 2155', 'e.g. YYYY, YY', 'https://mariadb.com/kb/en/year/', FALSE, TRUE, FALSE), ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARBINARY(size)', 'varbinary', 0, null, null, TRUE, null, null, null, null, null, null, null, null, 'https://mariadb.com/kb/en/varbinary/', FALSE, TRUE, FALSE), - ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARCHAR(size)', 'VARCHAR', 0, 65532, 255, TRUE, null, null, null, null, - null, null, null, null, 'https://mariadb.com/kb/en/VARCHAR/', FALSE, TRUE, FALSE); + ('d79cb089-363c-488b-9717-649e44d8fcc5', 'VARCHAR(size)', 'varchar', 0, 65532, 255, TRUE, null, null, null, null, + null, null, null, null, 'https://mariadb.com/kb/en/varchar/', FALSE, TRUE, FALSE); INSERT INTO `mdb_image_operators` (image_id, display_name, value, documentation) diff --git a/helm/dbrepo/files/create-event-listener.jar b/helm/dbrepo/files/create-event-listener.jar index 087747d1bce60c75c887a495e51d8b94617624f1..fdbd461988b553d11d6b24e64d63e9689e20bad0 100644 Binary files a/helm/dbrepo/files/create-event-listener.jar and b/helm/dbrepo/files/create-event-listener.jar differ