diff --git a/Makefile b/Makefile index 338c09001343b9c80789cb8f41a0d4c4dac9a2ad..9477d1fb72351f8bacd3881efeda6edf859f3b05 100644 --- a/Makefile +++ b/Makefile @@ -149,11 +149,6 @@ scan-search-db: trivy image --insecure --exit-code 0 "dbrepo-search-db" trivy image --insecure --exit-code 1 --severity CRITICAL "dbrepo-search-db" -scan-metadata-db: - trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-db-report.json "dbrepo-metadata-db" - trivy image --insecure --exit-code 0 "dbrepo-metadata-db" - trivy image --insecure --exit-code 1 --severity CRITICAL "dbrepo-metadata-db" - scan-data-db: docker pull "bitnami/mariadb:10.5" trivy image --insecure --exit-code 0 --format template --template "@.trivy/gitlab.tpl" -o ./.trivy/trivy-search-db-report.json "bitnami/mariadb:10.5" diff --git a/dbrepo-metadata-db/setup-schema.sql b/dbrepo-metadata-db/setup-schema.sql index d69d524079f6357f05a47913f99c923ff1967255..b6561d250327203abf02b3ffc26f0d41b949a2a6 100644 --- a/dbrepo-metadata-db/setup-schema.sql +++ b/dbrepo-metadata-db/setup-schema.sql @@ -145,6 +145,7 @@ CREATE TABLE IF NOT EXISTS `fda`.`mdb_columns` dfID bigint, cName VARCHAR(100), internal_name VARCHAR(100) NOT NULL, + alias VARCHAR(100), Datatype ENUM ('CHAR','VARCHAR','BINARY','VARBINARY','TINYBLOB','TINYTEXT','TEXT','BLOB','MEDIUMTEXT','MEDIUMBLOB','LONGTEXT','LONGBLOB','ENUM','SET','BIT','TINYINT','BOOL','SMALLINT','MEDIUMINT','INT','BIGINT','FLOAT','DOUBLE','DECIMAL','DATE','DATETIME','TIMESTAMP','TIME','YEAR'), length INT NULL, ordinal_position INTEGER NOT NULL, @@ -349,13 +350,13 @@ CREATE TABLE IF NOT EXISTS `fda`.`mdb_banner_messages` CREATE TABLE IF NOT EXISTS `fda`.`mdb_ontologies` ( - id bigint NOT NULL AUTO_INCREMENT, - prefix VARCHAR(8) NOT NULL, - uri TEXT NOT NULL, + id bigint NOT NULL AUTO_INCREMENT, + prefix VARCHAR(8) NOT NULL, + uri TEXT NOT NULL, uri_pattern TEXT, - sparql_endpoint TEXT NULL, + sparql_endpoint TEXT NULL, last_modified timestamp, - created timestamp NOT NULL DEFAULT NOW(), + created timestamp NOT NULL DEFAULT NOW(), UNIQUE (prefix), UNIQUE (uri(200)), PRIMARY KEY (id) diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java index ac21249ec5f26fe582c2f48e11c99dc800b9e7a9..d64bfd4db378c5807cdc68cf1db3419201fc7b22 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/query/QueryResultDto.java @@ -22,6 +22,9 @@ public class QueryResultDto { @NotNull(message = "result set is required") private List<Map<String, Object>> result; + @NotNull(message = "headers is required") + private List<Map<String, Integer>> headers; + @NotNull(message = "query id is required") private Long id; diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java index 4745442c0a7c59dd0f1e8ce8dcd7d8c7276ef610..e811991912c8188ae0506d8bc344eb53f208e90d 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnBriefDto.java @@ -37,6 +37,9 @@ public class ColumnBriefDto { @Schema(example = "mdb_date") private String internalName; + @Schema + private String alias; + @NotNull @JsonProperty("column_type") @Schema(example = "date") diff --git a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java index 48b0745c6cd715cadb4005bf54e3d60b26f67c91..eb748f1ec48dbceeff66923a056bfb125eee2c3a 100644 --- a/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java +++ b/dbrepo-metadata-service/api/src/main/java/at/tuwien/api/database/table/columns/ColumnDto.java @@ -53,6 +53,10 @@ public class ColumnDto { @Schema(example = "mdb_date") private String internalName; + @Field(name = "alias", type = FieldType.Keyword) + @Schema + private String alias; + @JsonProperty("date_format") @Field(name = "date_format", includeInParent = true, type = FieldType.Nested) private ImageDateDto dateFormat; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/Table.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/Table.java index f3141e1ab1112c7baf4d8307d7cb097390ad66ef..fe6edc3e4f8f5fcb06011bc0d9ef0fc694c4f094 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/Table.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/Table.java @@ -3,6 +3,7 @@ package at.tuwien.entities.database.table; import at.tuwien.entities.database.Database; import at.tuwien.entities.database.table.columns.TableColumn; import at.tuwien.entities.database.table.constraints.Constraints; +import at.tuwien.entities.user.User; import lombok.*; import lombok.extern.log4j.Log4j2; import net.sf.jsqlparser.statement.select.FromItem; @@ -44,10 +45,27 @@ public class Table { @Column(name = "created_by", columnDefinition = "VARCHAR(36)") private UUID createdBy; + @ToString.Exclude + @org.springframework.data.annotation.Transient + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumns({ + @JoinColumn(name = "created_by", referencedColumnName = "ID", insertable = false, updatable = false) + }) + private User creator; + + @JdbcTypeCode(java.sql.Types.VARCHAR) @Column(name = "owned_by", columnDefinition = "VARCHAR(36)") private UUID ownedBy; + @ToString.Exclude + @org.springframework.data.annotation.Transient + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumns({ + @JoinColumn(name = "owned_by", referencedColumnName = "ID", insertable = false, updatable = false) + }) + private User owner; + @Column(name = "tname", nullable = false) private String name; diff --git a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java index 364b74b02ac61f7ce8fe7b24149220c33aada07d..98c5d5d8895fb4839f539db0331fd23f9bedf7fd 100644 --- a/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java +++ b/dbrepo-metadata-service/entities/src/main/java/at/tuwien/entities/database/table/columns/TableColumn.java @@ -66,10 +66,8 @@ public class TableColumn implements Comparable<TableColumn> { @Column private Integer indexLength; - @Transient - @ToString.Exclude - @org.springframework.data.annotation.Transient - private transient String alias; + @Column + private String alias; @Column(name = "datatype", nullable = false) @Enumerated(EnumType.STRING) diff --git a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java index 8385f3eb1505b41dce08b57af58fcffa3f9980a1..d4d1fb168ab8bdf0fa03d361b5467cb4809d9598 100644 --- a/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java +++ b/dbrepo-metadata-service/repositories/src/main/java/at/tuwien/mapper/QueryMapper.java @@ -85,7 +85,13 @@ public interface QueryMapper { int[] idx = new int[]{1}; final Map<String, Object> map = new HashMap<>(); for (final TableColumn column : columns) { - final String columnOrAlias = column.getAlias() != null ? column.getAlias() : column.getInternalName(); + final String columnOrAlias; + if (column.getAlias() != null) { + log.debug("column {} has alias {}", column.getInternalName(), column.getAlias()); + columnOrAlias = column.getAlias(); + } else { + columnOrAlias = column.getInternalName(); + } if (List.of(TableColumnType.BLOB, TableColumnType.TINYBLOB, TableColumnType.MEDIUMBLOB, TableColumnType.LONGBLOB).contains(column.getColumnType())) { log.debug("column {} is of type blob", columnOrAlias); final Blob blob = result.getBlob(idx[0]++); @@ -100,8 +106,16 @@ public interface QueryMapper { } resultList.add(map); } + final int[] idx = new int[]{0}; + final List<Map<String, Integer>> headers = columns.stream() + .map(c -> (Map<String, Integer>) new LinkedHashMap<String, Integer>(){{ + put(c.getAlias() != null ? c.getAlias() : c.getInternalName(), idx[0]++); + }}) + .toList(); + log.debug("created ordered header list: {}", headers); return QueryResultDto.builder() .result(resultList) + .headers(headers) .build(); } @@ -627,15 +641,10 @@ public interface QueryMapper { return statement.toString(); } - default String queryToRawTimestampedQuery(String query, Database database, Instant timestamp, Boolean selection, Long page, Long size) - throws ImageNotSupportedException, QueryMalformedException { - log.trace("mapping query to timestamped query, query={}, database={}, timestamp={}, selection={}, page={}, size={}", - query, database, timestamp, selection, page, size); + default String queryToRawTimestampedQuery(String query, Instant timestamp, Boolean selection, Long page, Long size) { + log.trace("mapping query to timestamped query, query={}, timestamp={}, selection={}, page={}, size={}", + query, timestamp, selection, page, size); /* param check */ - if (!database.getContainer().getImage().getName().equals("mariadb")) { - log.error("Currently only MariaDB is supported"); - throw new ImageNotSupportedException("Currently only MariaDB is supported"); - } if (timestamp == null) { log.error("Timestamp is null"); throw new IllegalArgumentException("Please provide a timestamp before"); @@ -655,13 +664,6 @@ public interface QueryMapper { query = query.substring(0, query.length() - 1); } /* query check (this is enforced by the db also) */ - if (Stream.of("count").anyMatch(query::contains)) { - log.error("Query contains unsupported operation, one of {}", List.of("COUNT")); - } - if (Stream.of("delete", "update", "truncate", "create", "drop").anyMatch(query::contains)) { - log.error("Query attempts to modify the database"); - throw new QueryMalformedException("Query attempts to modify the database"); - } final StringBuilder sb = new StringBuilder(); if (selection) { /* is not a count query */ @@ -704,14 +706,9 @@ public interface QueryMapper { return columnsToRawFindAllQuery(table.getInternalName(), table.getColumns(), timestamp, size, page); } - default String viewToRawFindAllQuery(View view, Long size, Long page) - throws ImageNotSupportedException { + default String viewToRawFindAllQuery(View view, Long size, Long page) { log.trace("mapping view to find all query, view={}, size={}, page={}", view, size, page); /* param check */ - if (!view.getDatabase().getContainer().getImage().getName().equals("mariadb")) { - log.error("Currently only MariaDB is supported"); - throw new ImageNotSupportedException("Currently only MariaDB is supported"); - } return columnsToRawFindAllQuery(view.getInternalName(), view.getColumns(), null, size, page); } @@ -807,36 +804,36 @@ public interface QueryMapper { .toInstant(); } case BINARY, VARBINARY, BIT -> { - log.trace("mapping {} to binary", data); + log.trace("mapping {} -> binary", data); return Long.parseLong(String.valueOf(data), 2); } case TEXT, CHAR, VARCHAR, TINYTEXT, MEDIUMTEXT, LONGTEXT, ENUM, SET -> { - log.trace("mapping {} to character array", data); + log.trace("mapping {} -> string", data); return String.valueOf(data); } case BIGINT -> { - log.trace("mapping {} to bigint number", data); + log.trace("mapping {} -> biginteger", data); return new BigInteger(String.valueOf(data)); } case INT, TINYINT, SMALLINT, MEDIUMINT -> { - log.trace("mapping {} to int number", data); + log.trace("mapping {} -> integer", data); return Integer.parseInt(String.valueOf(data)); } case DECIMAL, FLOAT, DOUBLE -> { - log.trace("mapping {} to decimal number", data); + log.trace("mapping {} -> double", data); return Double.valueOf(String.valueOf(data)); } case BOOL -> { - log.trace("mapping {} to boolean", data); + log.trace("mapping {} -> boolean", data); return Boolean.valueOf(String.valueOf(data)); } case TIME -> { - log.trace("mapping {} to time", data); + log.trace("mapping {} -> time", data); return String.valueOf(data); } case YEAR -> { final String tmp = String.valueOf(data); - log.trace("mapping {} to year", tmp); + log.trace("mapping {} -> year", tmp); return tmp.substring(0, tmp.indexOf('-')); } } diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java index 65f4ca6ff63c1e92e4df314b1106ea3437649120..bd494caa52da8176cfaa2c5aaf859ac43c3c78c5 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/QueryEndpoint.java @@ -101,8 +101,8 @@ public class QueryEndpoint { endpointValidator.validateOnlyAccessOrPublic(databaseId, queryId, principal); /* execute */ final Query query = storeService.findOne(databaseId, queryId, principal); - final QueryResultDto result = queryService.reExecute(databaseId, query, page, size, - sortDirection, sortColumn, principal); + final QueryResultDto result = queryService.reExecute(databaseId, query, page, size, sortDirection, sortColumn, + principal); result.setId(queryId); log.trace("re-execute query resulted in result {}", result); return ResponseEntity.status(HttpStatus.ACCEPTED) diff --git a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java index 0d06774fa070a0d959b664983b960133b966cafd..0958d094742f71266de1a496fb31e21c556840f8 100644 --- a/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java +++ b/dbrepo-metadata-service/rest-service/src/main/java/at/tuwien/endpoints/ViewEndpoint.java @@ -193,7 +193,7 @@ public class ViewEndpoint { final Database database = databaseService.find(databaseId); log.trace("find view for database {}", database); final ViewDto view = viewMapper.viewToViewDto(viewService.findById(databaseId, viewId, principal)); - log.trace("find find resulted in view {}", view); + log.trace("find view resulted in view {}", view); return ResponseEntity.ok(view); } @@ -345,11 +345,11 @@ public class ViewEndpoint { } } /* find */ - log.trace("find view data for database {}", database); + log.debug("find view data for database with id {}", databaseId); final View view = viewService.findById(databaseId, viewId, principal); final QueryResultDto result = queryService.viewFindAll(databaseId, view, page, size, principal); - log.trace("execute view {}", view); - log.trace("find view data resulted in result {}", result); + log.trace("execute view data for view with id {}", viewId); + log.debug("find view data resulted in result {}", result); return ResponseEntity.ok() .body(result); } @@ -367,12 +367,12 @@ public class ViewEndpoint { log.debug("endpoint find view data count, databaseId={}, viewId={}, principal={}", databaseId, viewId, principal); /* find */ - final Database database = databaseService.find(databaseId); - log.trace("find view data for database {}", database); + databaseService.find(databaseId); + log.debug("find view data count for database with id {}", databaseId); final View view = viewService.findById(databaseId, viewId, principal); final Long result = queryService.viewCount(databaseId, view, principal); - log.trace("execute view {}", view); - log.trace("find view data resulted in result {}", result); + log.trace("execute view data count for view with id {}", viewId); + log.debug("find view data count resulted in result {}", result); return ResponseEntity.ok() .body(result); } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewIdxRepositoryIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewIdxRepositoryIntegrationTest.java index ac7360e38d2551dc3d61ad9de7d3489b896b75de..9b96beefef1efe37882ed3e2ca875b11b86ebaed 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewIdxRepositoryIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewIdxRepositoryIntegrationTest.java @@ -77,7 +77,7 @@ public class ViewIdxRepositoryIntegrationTest extends BaseUnitTest { private static final OpensearchContainer opensearchContainer = new OpensearchContainer(DockerImageName.parse("opensearchproject/opensearch:2.8.0")); @DynamicPropertySource - static void elasticsearchProperties(DynamicPropertyRegistry registry) { + static void openSearchProperties(DynamicPropertyRegistry registry) { final int idx = opensearchContainer.getHttpHostAddress().lastIndexOf(':'); registry.add("spring.opensearch.host", () -> "127.0.0.1"); registry.add("spring.opensearch.port", () -> opensearchContainer.getHttpHostAddress().substring(idx + 1)); @@ -93,7 +93,7 @@ public class ViewIdxRepositoryIntegrationTest extends BaseUnitTest { TABLE_2.setColumns(TABLE_2_COLUMNS); /* metadata database */ imageRepository.save(IMAGE_1); - userRepository.save(USER_1); + userRepository.saveAll(List.of(USER_1, USER_2)); containerRepository.save(CONTAINER_1); databaseRepository.save(DATABASE_1_SIMPLE); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE)); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewRepositoryIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewRepositoryIntegrationTest.java index 844d798d6773db2094e15ce15183c7c1e71dfdf0..bcb12ab0b35c9508881190004f501ddc84ff5138 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewRepositoryIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/repository/ViewRepositoryIntegrationTest.java @@ -55,8 +55,7 @@ public class ViewRepositoryIntegrationTest extends BaseUnitTest { @BeforeEach public void beforeEach() { imageRepository.save(IMAGE_1); - userRepository.save(USER_1); - userRepository.save(USER_2); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3)); containerRepository.saveAll(List.of(CONTAINER_1_SIMPLE, CONTAINER_2_SIMPLE)); databaseRepository.saveAll(List.of(DATABASE_1_SIMPLE, DATABASE_2_SIMPLE)); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE, TABLE_3_SIMPLE, TABLE_4_SIMPLE, TABLE_5_SIMPLE, TABLE_6_SIMPLE, TABLE_7_SIMPLE)); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java index 580a9d454526e0c66ed2a39e3c187efc06c59e6a..f31408c4865ee20159d10e556be72d0023ac15b0 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/IdentifierServiceIntegrationTest.java @@ -87,7 +87,7 @@ public class IdentifierServiceIntegrationTest extends BaseUnitTest { private static final OpensearchContainer opensearchContainer = new OpensearchContainer(DockerImageName.parse("opensearchproject/opensearch:2.8.0")); @DynamicPropertySource - static void elasticsearchProperties(DynamicPropertyRegistry registry) { + static void openSearchProperties(DynamicPropertyRegistry registry) { final int idx = opensearchContainer.getHttpHostAddress().lastIndexOf(':'); registry.add("spring.opensearch.host", () -> "127.0.0.1"); registry.add("spring.opensearch.port", () -> opensearchContainer.getHttpHostAddress().substring(idx + 1)); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java index 07fa1e92b65492df0e267077430297d6f82f77ab..32f61193982e764f573ccfd92ee5e5b60593c355 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/QueryServiceIntegrationTest.java @@ -87,8 +87,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { MariaDbConfig.createInitDatabase(CONTAINER_1, DATABASE_1); /* metadata database */ imageRepository.save(IMAGE_1); - userRepository.save(USER_1); - userRepository.save(USER_2); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3)); containerRepository.saveAll(List.of(CONTAINER_1_SIMPLE, CONTAINER_2_SIMPLE)); databaseRepository.saveAll(List.of(DATABASE_1_SIMPLE, DATABASE_2_SIMPLE)); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE, TABLE_3_SIMPLE, TABLE_4_SIMPLE, TABLE_5_SIMPLE, TABLE_6_SIMPLE, TABLE_7_SIMPLE)); @@ -301,8 +300,10 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT n.`firstname`, n.`lastname`, n.`birth`, n.`reminder`, z.`animal_name`, z.`legs` FROM `likes` l JOIN `names` n ON l.`name_id` = n.`id` JOIN `mock_view` z ON z.`id` = l.`zoo_id`") .build(); - /* test */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; + + /* test */ final QueryResultDto response = queryService.execute(DATABASE_2_ID, request, USER_1_PRINCIPAL, 0L, 100L, null, null); assertEquals(4L, response.getResultNumber()); assertNotNull(response.getResult()); @@ -338,8 +339,10 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT `location`, `lng` FROM `weather_location` WHERE `lat` IS NULL") .build(); - /* test */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; + + /* test */ final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 100L, null, null); assertEquals(1L, response.getResultNumber()); @@ -358,8 +361,10 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT `location` FROM `weather_location` WHERE `lat` IS NULL") .build(); - /* test */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; + + /* test */ final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 100L, null, null); assertEquals(1L, response.getResultNumber()); @@ -379,8 +384,10 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT `lat`, `lng` FROM `weather_location` WHERE `lat` IS NULL") .build(); - /* test */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; + + /* test */ final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 100L, null, null); assertEquals(1L, response.getResultNumber()); @@ -395,8 +402,10 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT aus.location as a, loc.location from weather_aus aus, weather_location loc") .build(); - /* test */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; + + /* test */ final QueryResultDto response = queryService.execute(DATABASE_1_ID, request, USER_1_PRINCIPAL, 0L, 100L, null, null); assertEquals(9L, response.getResultNumber()); assertNotNull(response.getResult()); @@ -430,7 +439,7 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { .statement("SELECT aus.location as a, loc.location from weather.weather_aus aus, weather.weather_location loc") .build(); - /* mock */ + /* pre-condition */ Thread.sleep(1000) /* wait for test container some more */; /* test */ @@ -459,6 +468,36 @@ public class QueryServiceIntegrationTest extends BaseUnitTest { assertEquals("Vienna", result.get(8).get("location")); } + @Test + public void viewFindAll_succeeds() throws DatabaseConnectionException, TableMalformedException, + DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, UserNotFoundException, + InterruptedException, ViewMalformedException, PaginationException, ViewNotFoundException { + + /* pre-condition */ + Thread.sleep(1000) /* wait for test container some more */; + + /* test */ + final QueryResultDto response = queryService.viewFindAll(DATABASE_1_ID, VIEW_2, 0L, 10L, USER_1_PRINCIPAL); + assertNotNull(response.getResult()); + final List<Map<String, Object>> result = response.getResult(); + /* values */ + assertEquals(0.6, result.get(0).get("rainfall")); + assertEquals("Albury", result.get(0).get("loc")); + assertEquals(13.4, result.get(0).get("mintemp")); + assertEquals(0.0, result.get(1).get("rainfall")); + assertEquals("Albury", result.get(1).get("loc")); + assertEquals(7.4, result.get(1).get("mintemp")); + assertEquals(0.0, result.get(2).get("rainfall")); + assertEquals("Albury", result.get(2).get("loc")); + assertEquals(12.9, result.get(2).get("mintemp")); + /* ordering */ + final String[] keys = result.get(0).keySet().toArray(new String[0]); + assertEquals("date", keys[0]); + assertEquals("loc", keys[1]); + assertEquals("rainfall", keys[2]); + assertEquals("mintemp", keys[3]); + } + @Test public void count_emptySet_succeeds() throws DatabaseConnectionException, TableMalformedException, DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, UserNotFoundException, diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationModifyTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationModifyTest.java index e7d733a529676037691575ccd27d352e46f84c5c..13012ab5bb0084d7f58bdc0d24b913ea9e3633dc 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationModifyTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/StoreServiceIntegrationModifyTest.java @@ -79,8 +79,7 @@ public class StoreServiceIntegrationModifyTest extends BaseUnitTest { /* metadata database */ imageRepository.save(IMAGE_1); containerRepository.save(CONTAINER_1); - userRepository.save(USER_1); - userRepository.save(USER_5); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3, USER_4, USER_5)); databaseRepository.save(DATABASE_1_SIMPLE); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE)); tableColumnRepository.saveAll(TABLE_1_COLUMNS); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java index 8d632a4ef037dfb56fd69494f043f9a91bec3602..17b54ee71a59560bf59de877a4e5eede3f5dd0a3 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/TableServiceIntegrationReadTest.java @@ -62,7 +62,7 @@ public class TableServiceIntegrationReadTest extends BaseUnitTest { @BeforeEach public void beforeEach() throws SQLException { imageRepository.save(IMAGE_1); - userRepository.saveAll(List.of(USER_1, USER_2)); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3)); containerRepository.save(CONTAINER_1_SIMPLE); containerRepository.save(CONTAINER_2_SIMPLE); databaseRepository.save(DATABASE_1_SIMPLE); diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java index 3ce4672df421ea673deadd3b7a398f62ee04099f..bc5b260aee74d80099bc4b016503d177f38cd904 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServiceIntegrationTest.java @@ -6,6 +6,7 @@ import at.tuwien.api.database.ViewCreateDto; import at.tuwien.config.MariaDbConfig; import at.tuwien.config.MariaDbContainerConfig; import at.tuwien.entities.database.View; +import at.tuwien.entities.database.table.columns.TableColumn; import at.tuwien.exception.*; import at.tuwien.repository.mdb.*; import lombok.extern.log4j.Log4j2; @@ -39,7 +40,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; @Log4j2 @Testcontainers @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) -@EnableAutoConfiguration(exclude= RabbitAutoConfiguration.class) +@EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @SpringBootTest @ExtendWith(SpringExtension.class) @MockAmqp @@ -79,7 +80,7 @@ public class ViewServiceIntegrationTest extends BaseUnitTest { private static final OpensearchContainer opensearchContainer = new OpensearchContainer(DockerImageName.parse("opensearchproject/opensearch:2.8.0")); @DynamicPropertySource - static void elasticsearchProperties(DynamicPropertyRegistry registry) { + static void openSearchProperties(DynamicPropertyRegistry registry) { final int idx = opensearchContainer.getHttpHostAddress().lastIndexOf(':'); registry.add("spring.opensearch.host", () -> "127.0.0.1"); registry.add("spring.opensearch.port", () -> opensearchContainer.getHttpHostAddress().substring(idx + 1)); @@ -97,7 +98,7 @@ public class ViewServiceIntegrationTest extends BaseUnitTest { public void beforeEach() { /* metadata database */ imageRepository.save(IMAGE_1); - userRepository.saveAll(List.of(USER_1, USER_2)); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3)); containerRepository.saveAll(List.of(CONTAINER_1_SIMPLE, CONTAINER_2_SIMPLE)); databaseRepository.saveAll(List.of(DATABASE_1_SIMPLE, DATABASE_2_SIMPLE)); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE, TABLE_3_SIMPLE, TABLE_4_SIMPLE, TABLE_5_SIMPLE, TABLE_6_SIMPLE, TABLE_7_SIMPLE)); @@ -173,4 +174,34 @@ public class ViewServiceIntegrationTest extends BaseUnitTest { assertNull(row2.get("lng")); } + @Test + public void create_withAlias_succeeds() throws DatabaseNotFoundException, UserNotFoundException, + DatabaseConnectionException, ViewMalformedException, QueryMalformedException { + final ViewCreateDto request = ViewCreateDto.builder() + .name(VIEW_2_NAME + "_with_alias") + .query(VIEW_2_QUERY) + .isPublic(VIEW_2_PUBLIC) + .build(); + + /* test */ + final View response = viewService.create(DATABASE_1_ID, request, USER_1_PRINCIPAL); + assertEquals(VIEW_2_NAME + "_with_alias", response.getName()); + assertEquals(VIEW_2_INTERNAL_NAME + "_with_alias", response.getInternalName()); + assertEquals(VIEW_2_QUERY, response.getQuery()); + final List<TableColumn> columns = response.getColumns(); + assertEquals(4, columns.size()); + final TableColumn column0 = columns.get(0); + assertEquals("date", column0.getInternalName()); + assertNull(column0.getAlias()); + final TableColumn column1 = columns.get(1); + assertEquals("location", column1.getInternalName()); + assertEquals("loc", column1.getAlias()); + final TableColumn column2 = columns.get(2); + assertEquals("rainfall", column2.getInternalName()); + assertNull(column2.getAlias()); + final TableColumn column3 = columns.get(3); + assertEquals("mintemp", column3.getInternalName()); + assertNull(column3.getAlias()); + } + } diff --git a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServicePersistenceIntegrationTest.java b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServicePersistenceIntegrationTest.java index a1e884e3374496b22aa96dfbbdf8a968037c293d..d29f53845a291cf7737c431b936aff629cf02ae2 100644 --- a/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServicePersistenceIntegrationTest.java +++ b/dbrepo-metadata-service/rest-service/src/test/java/at/tuwien/service/ViewServicePersistenceIntegrationTest.java @@ -77,7 +77,7 @@ public class ViewServicePersistenceIntegrationTest extends BaseUnitTest { public void beforeEach() { /* metadata database */ imageRepository.save(IMAGE_1); - userRepository.saveAll(List.of(USER_1, USER_2)); + userRepository.saveAll(List.of(USER_1, USER_2, USER_3)); containerRepository.saveAll(List.of(CONTAINER_1_SIMPLE, CONTAINER_2_SIMPLE)); databaseRepository.saveAll(List.of(DATABASE_1_SIMPLE, DATABASE_2_SIMPLE)); tableRepository.saveAll(List.of(TABLE_1_SIMPLE, TABLE_2_SIMPLE, TABLE_3_SIMPLE, TABLE_4_SIMPLE, TABLE_5_SIMPLE, TABLE_6_SIMPLE, TABLE_7_SIMPLE)); diff --git a/dbrepo-metadata-service/rest-service/src/test/resources/application.properties b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties index a004db1bceab10545f026b3752c6db633ddc80b2..9002d61ea23c22e68787be490ab9a15df260e67e 100644 --- a/dbrepo-metadata-service/rest-service/src/test/resources/application.properties +++ b/dbrepo-metadata-service/rest-service/src/test/resources/application.properties @@ -16,7 +16,8 @@ spring.jpa.hibernate.ddl-auto=create # logging logging.level.root=error -logging.level.at.tuwien.=${LOG_LEVEL:-debug} +logging.level.at.tuwien.=debug +logging.level.at.tuwien.service.impl.=trace # rabbitmq fda.broker.endpoint=http://localhost:15672 diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java index e974f6eac844814716a6f8c791e4f806aeadf893..534b30c69b1007dbed44cb14813b4cc34d84e572 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/QueryService.java @@ -66,10 +66,10 @@ public interface QueryService { * @throws ColumnParseException The column mapping/parsing failed. * @throws QueryMalformedException The query is malformed. */ - QueryResultDto reExecute(Long databaseId, Query query, Long page, Long size, - SortType sortDirection, String sortColumn, Principal principal) - throws QueryMalformedException, DatabaseNotFoundException, ImageNotSupportedException, ColumnParseException, - DatabaseConnectionException, TableMalformedException, QueryStoreException, UserNotFoundException; + QueryResultDto reExecute(Long databaseId, Query query, Long page, Long size, SortType sortDirection, + String sortColumn, Principal principal) throws QueryMalformedException, + DatabaseNotFoundException, ImageNotSupportedException, ColumnParseException, DatabaseConnectionException, + TableMalformedException, QueryStoreException, UserNotFoundException; /** * Re-Executes the count-statement of an arbitrary query on the database. We allow the user to only view @@ -151,10 +151,10 @@ public interface QueryService { * @throws ViewMalformedException The table is malformed. * @throws QueryMalformedException The query is malformed. */ - QueryResultDto viewFindAll(Long databaseId, View view, - Long page, Long size, Principal principal) throws ViewNotFoundException, DatabaseNotFoundException, - ImageNotSupportedException, DatabaseConnectionException, ViewMalformedException, PaginationException, - QueryMalformedException, UserNotFoundException, TableMalformedException; + QueryResultDto viewFindAll(Long databaseId, View view, Long page, Long size, Principal principal) + throws ViewNotFoundException, DatabaseNotFoundException, ImageNotSupportedException, + DatabaseConnectionException, ViewMalformedException, PaginationException, QueryMalformedException, + UserNotFoundException, TableMalformedException; /** * Finds one query by database id and query id. @@ -171,9 +171,9 @@ public interface QueryService { * @throws QueryNotFoundException THe query was not found in the query store. * @throws QueryMalformedException The query is malformed. */ - ExportResource findOne(Long databaseId, Long queryId, Principal principal) - throws DatabaseNotFoundException, ImageNotSupportedException, TableMalformedException, - FileStorageException, QueryStoreException, QueryNotFoundException, QueryMalformedException, DatabaseConnectionException, UserNotFoundException; + ExportResource findOne(Long databaseId, Long queryId, Principal principal) throws DatabaseNotFoundException, + ImageNotSupportedException, TableMalformedException, FileStorageException, QueryStoreException, + QueryNotFoundException, QueryMalformedException, DatabaseConnectionException, UserNotFoundException; /** * Count the total tuples for a given table id within a database id at a given time. diff --git a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java index cc58dc9f55d8e31ec38626dc50c8776b363c7d3d..074737f8bfd45ff0816d9be733e21c8b923468b8 100644 --- a/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java +++ b/dbrepo-metadata-service/services/src/main/java/at/tuwien/service/impl/QueryServiceImpl.java @@ -71,8 +71,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService @Override @Transactional(readOnly = true) - public QueryResultDto execute(Long databaseId, ExecuteStatementDto statement, - Principal principal, Long page, Long size, SortType sortDirection, String sortColumn) + public QueryResultDto execute(Long databaseId, ExecuteStatementDto statement, Principal principal, Long page, + Long size, SortType sortDirection, String sortColumn) throws DatabaseNotFoundException, ImageNotSupportedException, QueryMalformedException, QueryStoreException, ColumnParseException, UserNotFoundException, DatabaseConnectionException, TableMalformedException, KeycloakRemoteException, AccessDeniedException { @@ -102,7 +102,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService log.error("Failed to map/parse columns: {}", e.getMessage()); throw new ColumnParseException("Failed to map/parse columns: " + e.getMessage(), e); } - final String statement = queryMapper.queryToRawTimestampedQuery(query.getQuery(), database, query.getCreated(), true, page, size); + final String statement = queryMapper.queryToRawTimestampedQuery(query.getQuery(), query.getCreated(), true, page, size); final QueryResultDto dto = executeNonPersistent(databaseId, statement, columns); dto.setId(query.getId()); dto.setResultNumber(query.getResultNumber()); @@ -126,7 +126,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService log.error("Failed to map/parse columns: {}", e.getMessage()); throw new ColumnParseException("Failed to map/parse columns: " + e.getMessage(), e); } - final String statement = queryMapper.queryToRawTimestampedQuery(query.getQuery(), database, query.getCreated(), false, null, null); + final String statement = queryMapper.queryToRawTimestampedQuery(query.getQuery(), query.getCreated(), false, null, null); return executeCountNonPersistent(databaseId, statement); } @@ -148,8 +148,8 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService database.getContainer(), database); try { final Connection connection = dataSource.getConnection(); + log.trace("preparing statement {}", statement); final PreparedStatement preparedStatement = prepareStatement(connection, statement); - log.trace("prepared statement {}", statement); final ResultSet resultSet = preparedStatement.executeQuery(); return queryMapper.resultListToQueryResultDto(columns, resultSet); } catch (SQLException e) { @@ -194,13 +194,10 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService @Override @Transactional(readOnly = true) - public QueryResultDto viewFindAll(Long databaseId, View view, - Long page, Long size, Principal principal) throws DatabaseNotFoundException, - ImageNotSupportedException, QueryMalformedException, TableMalformedException { - /* find */ + public QueryResultDto viewFindAll(Long databaseId, View view, Long page, Long size, Principal principal) + throws DatabaseNotFoundException, QueryMalformedException, TableMalformedException { /* run query */ - String statement = queryMapper.viewToRawFindAllQuery(view, size, page); - return executeNonPersistent(databaseId, statement, view.getColumns()); + return executeNonPersistent(databaseId, view.getQuery(), view.getColumns()); } @Override @@ -506,7 +503,7 @@ public class QueryServiceImpl extends HibernateConnector implements QueryService } @Transactional(readOnly = true) - protected boolean columnMatches(TableColumn column, String tableOrView) { + public boolean columnMatches(TableColumn column, String tableOrView) { if (column.getTable().getInternalName().equals(tableOrView)) { /* matches table name */ return true; diff --git a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java index 8e7fa5ab4bcb31efa6fa973f5ed601bb165b09fc..13b181972e95832f35534de480a49ed0b1bcf058 100644 --- a/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java +++ b/dbrepo-metadata-service/test/src/main/java/at/tuwien/test/BaseTest.java @@ -614,7 +614,7 @@ public abstract class BaseTest { .affiliation(USER_5_AFFILIATION) .themeDark(USER_5_THEME_DARK) .mariadbPassword(USER_5_DATABASE_PASSWORD) - .build(); + .build(); public final static UUID USER_6_ID = UUID.fromString("28ff851d-d7bc-4422-959c-edd7a5b15630"); public final static String USER_6_USERNAME = "system"; @@ -3115,8 +3115,8 @@ public abstract class BaseTest { public final static Long QUERY_3_ID = 3L; public final static String QUERY_3_STATEMENT = "SELECT `location`, `mintemp` FROM `weather_aus` WHERE `mintemp` > 10"; public final static String QUERY_3_QUERY_HASH = "a3d3dd94ebc7653bb5a3b55dd8ed5e91d3d13c335c6855a1eb4eb7ca14c36ced"; - public final static Long QUERY_3_CONTAINER_ID = CONTAINER_2_ID; - public final static Long QUERY_3_DATABASE_ID = DATABASE_2_ID; + public final static Long QUERY_3_CONTAINER_ID = CONTAINER_1_ID; + public final static Long QUERY_3_DATABASE_ID = DATABASE_1_ID; public final static String QUERY_3_RESULT_HASH = "ff3f7cbe1b96d396957f6e39e55b8b1b577fa3d305d4795af99594cfd30cb80d"; public final static Instant QUERY_3_CREATED = Instant.now().minus(3, MINUTES); public final static Instant QUERY_3_EXECUTION = Instant.now().minus(1, MINUTES); @@ -5078,23 +5078,10 @@ public abstract class BaseTest { public final static Long VIEW_2_CONTAINER_ID = CONTAINER_1_ID; public final static Long VIEW_2_DATABASE_ID = DATABASE_1_ID; public final static Boolean VIEW_2_PUBLIC = true; - public final static String VIEW_2_QUERY = "select `date`, `location`, `mintemp`, `rainfall` from `weather_aus` where `location` = 'Albury'"; - public final static String VIEW_2_QUERY_HASH = "c76efcbab7e117ed286fd6c0f766178727debfeb5544633f8fbfaf2230340d17"; + public final static String VIEW_2_QUERY = "select `date`, `location` as loc, `rainfall`, `mintemp` from `weather_aus` where `location` = 'Albury'"; + public final static String VIEW_2_QUERY_HASH = "987fc946772ffb6d85060262dcb5df419692a1f6772ea995e3dedb53c191e984"; public final static List<TableColumn> VIEW_2_COLUMNS = List.of(TableColumn.builder() - .id(COLUMN_1_1_ID) - .ordinalPosition(COLUMN_1_1_ORDINALPOS) - .table(TABLE_1) - .name(COLUMN_1_1_NAME) - .internalName(COLUMN_1_1_INTERNAL_NAME) - .columnType(COLUMN_1_1_TYPE) - .isNullAllowed(COLUMN_1_1_NULL) - .autoGenerated(COLUMN_1_1_AUTO_GENERATED) - .isPrimaryKey(COLUMN_1_1_PRIMARY) - .enums(COLUMN_1_1_ENUM_VALUES) - .sets(COLUMN_1_1_SET_VALUES) - .build(), - TableColumn.builder() .id(COLUMN_1_2_ID) .ordinalPosition(COLUMN_1_2_ORDINALPOS) .table(TABLE_1) @@ -5113,6 +5100,7 @@ public abstract class BaseTest { .ordinalPosition(COLUMN_1_3_ORDINALPOS) .table(TABLE_1) .name(COLUMN_1_3_NAME) + .alias("loc") .internalName(COLUMN_1_3_INTERNAL_NAME) .columnType(COLUMN_1_3_TYPE) .isNullAllowed(COLUMN_1_3_NULL) @@ -5121,19 +5109,6 @@ public abstract class BaseTest { .enums(COLUMN_1_3_ENUM_VALUES) .sets(COLUMN_1_3_SET_VALUES) .build(), - TableColumn.builder() - .id(COLUMN_1_4_ID) - .ordinalPosition(COLUMN_1_4_ORDINALPOS) - .table(TABLE_1) - .name(COLUMN_1_4_NAME) - .internalName(COLUMN_1_4_INTERNAL_NAME) - .columnType(COLUMN_1_4_TYPE) - .isNullAllowed(COLUMN_1_4_NULL) - .autoGenerated(COLUMN_1_4_AUTO_GENERATED) - .isPrimaryKey(COLUMN_1_4_PRIMARY) - .enums(COLUMN_1_4_ENUM_VALUES) - .sets(COLUMN_1_4_SET_VALUES) - .build(), TableColumn.builder() .id(COLUMN_1_5_ID) .ordinalPosition(COLUMN_1_5_ORDINALPOS) @@ -5146,6 +5121,19 @@ public abstract class BaseTest { .isPrimaryKey(COLUMN_1_5_PRIMARY) .enums(COLUMN_1_5_ENUM_VALUES) .sets(COLUMN_1_5_SET_VALUES) + .build(), + TableColumn.builder() + .id(COLUMN_1_4_ID) + .ordinalPosition(COLUMN_1_4_ORDINALPOS) + .table(TABLE_1) + .name(COLUMN_1_4_NAME) + .internalName(COLUMN_1_4_INTERNAL_NAME) + .columnType(COLUMN_1_4_TYPE) + .isNullAllowed(COLUMN_1_4_NULL) + .autoGenerated(COLUMN_1_4_AUTO_GENERATED) + .isPrimaryKey(COLUMN_1_4_PRIMARY) + .enums(COLUMN_1_4_ENUM_VALUES) + .sets(COLUMN_1_4_SET_VALUES) .build()); public final static View VIEW_2 = View.builder() @@ -5390,7 +5378,7 @@ public abstract class BaseTest { .isPrimaryKey(COLUMN_4_7_PRIMARY) .enums(COLUMN_4_7_ENUM_VALUES) .sets(COLUMN_4_7_SET_VALUES) - .build(), + .build(), TableColumn.builder() .id(COLUMN_4_9_ID) .ordinalPosition(COLUMN_4_9_ORDINALPOS) diff --git a/dbrepo-search-sync-agent/rest-service/src/test/java/at/tuwien/app/SearchSyncComponentTest.java b/dbrepo-search-sync-agent/rest-service/src/test/java/at/tuwien/app/SearchSyncComponentTest.java index 81e8880fd40382a364cb572c5e3d32b2a4cab8e1..d0cc176edf179a48848971c6058983cb78ff8059 100644 --- a/dbrepo-search-sync-agent/rest-service/src/test/java/at/tuwien/app/SearchSyncComponentTest.java +++ b/dbrepo-search-sync-agent/rest-service/src/test/java/at/tuwien/app/SearchSyncComponentTest.java @@ -120,7 +120,7 @@ public class SearchSyncComponentTest extends BaseUnitTest { @BeforeEach public void beforeEach() { licenseRepository.save(LICENSE_1); - userRepository.save(USER_1); + userRepository.saveAll(List.of(USER_1, USER_2)); imageRepository.save(IMAGE_1); containerRepository.save(CONTAINER_1); databaseRepository.save(DATABASE_1); @@ -159,7 +159,7 @@ public class SearchSyncComponentTest extends BaseUnitTest { assertEquals(1, units.size()); final List<UserDto> users = StreamSupport.stream(userIdxRepository.findAll().spliterator(), false) .toList(); - assertEquals(1, users.size()); + assertEquals(2, users.size()); final List<ViewDto> views = StreamSupport.stream(viewIdxRepository.findAll().spliterator(), false) .toList(); assertEquals(1, views.size()); diff --git a/dbrepo-ui/api/query.service.js b/dbrepo-ui/api/query.service.js index 118f97f31c2c7666bda0ad8f92b5568031c204ab..857464873a17ffaece8ce68026b7d7d4cfcbaa24 100644 --- a/dbrepo-ui/api/query.service.js +++ b/dbrepo-ui/api/query.service.js @@ -206,7 +206,8 @@ class QueryService { resolve(result) }) .catch((error) => { - const { code, message } = error + const { code } = error + const { message } = error.response.data console.error('Failed to re-execute view', error) Vue.$toast.error(`[${code}] Failed to re-execute view: ${message}`) reject(error) @@ -223,7 +224,8 @@ class QueryService { resolve(count) }) .catch((error) => { - const { code, message } = error + const { code } = error + const { message } = error.response.data console.error('Failed to re-execute view count', error) Vue.$toast.error(`[${code}] Failed to re-execute view count: ${message}`) reject(error) diff --git a/dbrepo-ui/components/query/Results.vue b/dbrepo-ui/components/query/Results.vue index 94a61b3eb0a030810c893be8b7634ee4f2e7466d..3249f99e18ba8a3889862865a95024fd48f16ff5 100644 --- a/dbrepo-ui/components/query/Results.vue +++ b/dbrepo-ui/components/query/Results.vue @@ -47,8 +47,8 @@ export default { if (this.type === 'view' && this.view && this.view.columns) { return this.view.columns.map((c) => { return { - text: c.internal_name, - value: c.internal_name, + text: c.alias ? c.alias : c.internal_name, + value: c.alias ? c.alias : c.internal_name, sortable: false } }) @@ -80,13 +80,6 @@ export default { this.loading-- }) }, - buildHeaders (firstLine) { - return Object.keys(firstLine).map(k => ({ - text: k, - value: k, - sortable: false - })) - }, reExecute (id) { if (id === null) { return @@ -136,9 +129,13 @@ export default { } }, mapResults (data) { - if (data.result.length) { - this.result.headers = this.buildHeaders(data.result[0]) - } + this.result.headers = data.headers.map((h) => { + return { + text: Object.keys(h)[0], + value: Object.keys(h)[0], + sortable: false + } + }) console.debug('query result', data) this.result.rows = data.result if (this.total < 0 && data.result_number != null) { diff --git a/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue b/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue index 96ec047712f9e095f6bce3b186790303637edd0a..8a3df803ef2ba03aef52c1e3d5eec68ca534723e 100644 --- a/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue +++ b/dbrepo-ui/pages/database/_database_id/table/_table_id/data.vue @@ -142,13 +142,10 @@ export default { return this.version.substring(0, 10) + 'T' + this.version.substring(11, 19) + 'Z' }, canModify () { - if (!this.user || !this.access || !this.table || !this.table.creator) { + if (!this.user || !this.access || !this.table) { return false } - if (this.table.creator.username === this.user.username) { - return true - } - if (this.access.type === 'write_own' && this.table.creator.username === this.user.username) { + if (this.access.type === 'write_own' && this.table.owner.id === this.user.id) { return true } return this.access.type === 'write_all' @@ -296,7 +293,8 @@ export default { return row }) }) - .catch(() => { + .catch((error) => { + console.error('load data resulted in error', error) this.error = true }) .finally(() => {