diff --git a/backend/src/main/java/com/bakdata/conquery/apiv1/frontend/FrontendSelect.java b/backend/src/main/java/com/bakdata/conquery/apiv1/frontend/FrontendSelect.java index b698e7b26a..95f9e1c94b 100644 --- a/backend/src/main/java/com/bakdata/conquery/apiv1/frontend/FrontendSelect.java +++ b/backend/src/main/java/com/bakdata/conquery/apiv1/frontend/FrontendSelect.java @@ -1,7 +1,6 @@ package com.bakdata.conquery.apiv1.frontend; import com.bakdata.conquery.models.identifiable.ids.specific.SelectId; -import com.bakdata.conquery.models.types.ResultType; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Builder; import lombok.Data; @@ -15,7 +14,7 @@ public class FrontendSelect { private SelectId id; private String label; private String description; - private ResultType resultType; + private String resultType; @JsonProperty("default") private Boolean isDefault; } diff --git a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/FrontEndConceptBuilder.java b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/FrontEndConceptBuilder.java index 07e3dd23b8..721fc2c920 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/FrontEndConceptBuilder.java +++ b/backend/src/main/java/com/bakdata/conquery/models/datasets/concepts/FrontEndConceptBuilder.java @@ -1,10 +1,23 @@ package com.bakdata.conquery.models.datasets.concepts; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.bakdata.conquery.apiv1.frontend.*; +import com.bakdata.conquery.apiv1.frontend.FrontendFilterConfiguration; +import com.bakdata.conquery.apiv1.frontend.FrontendList; +import com.bakdata.conquery.apiv1.frontend.FrontendNode; +import com.bakdata.conquery.apiv1.frontend.FrontendRoot; +import com.bakdata.conquery.apiv1.frontend.FrontendSecondaryId; +import com.bakdata.conquery.apiv1.frontend.FrontendSelect; +import com.bakdata.conquery.apiv1.frontend.FrontendTable; +import com.bakdata.conquery.apiv1.frontend.FrontendValidityDate; +import com.bakdata.conquery.apiv1.frontend.FrontendValue; import com.bakdata.conquery.io.storage.NamespaceStorage; import com.bakdata.conquery.models.auth.entities.Subject; import com.bakdata.conquery.models.auth.permissions.Ability; @@ -159,7 +172,7 @@ public FrontendSelect createSelect(Select select) { .id(select.getId()) .label(select.getLabel()) .description(select.getDescription()) - .resultType(select.getResultType()) + .resultType(select.getResultType().typeInfo()) .isDefault(select.isDefault()) .build(); } diff --git a/backend/src/main/java/com/bakdata/conquery/models/types/ResultType.java b/backend/src/main/java/com/bakdata/conquery/models/types/ResultType.java index 02c82abfe1..52ccbfbea9 100644 --- a/backend/src/main/java/com/bakdata/conquery/models/types/ResultType.java +++ b/backend/src/main/java/com/bakdata/conquery/models/types/ResultType.java @@ -11,15 +11,12 @@ import c10n.C10N; import com.bakdata.conquery.internationalization.Results; -import com.bakdata.conquery.io.cps.CPSBase; -import com.bakdata.conquery.io.cps.CPSType; import com.bakdata.conquery.models.common.daterange.CDateRange; import com.bakdata.conquery.models.config.LocaleConfig; import com.bakdata.conquery.models.events.MajorTypeId; import com.bakdata.conquery.models.query.PrintSettings; import com.bakdata.conquery.sql.execution.ResultSetProcessor; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.google.common.base.Preconditions; import lombok.AccessLevel; import lombok.EqualsAndHashCode; @@ -29,28 +26,9 @@ import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; -@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "type") -@CPSBase @Slf4j public abstract class ResultType { - public String printNullable(PrintSettings cfg, Object f) { - if (f == null) { - return ""; - } - return print(cfg, f); - } - - protected String print(PrintSettings cfg, @NonNull Object f) { - return f.toString(); - } - - public abstract String typeInfo(); - - public abstract T getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException; - - protected abstract List getFromResultSetAsList(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException; - public static ResultType resolveResultType(MajorTypeId majorTypeId) { return switch (majorTypeId) { case STRING -> StringT.INSTANCE; @@ -63,21 +41,27 @@ public static ResultType resolveResultType(MajorTypeId majorTypeId) { }; } - abstract static class PrimitiveResultType extends ResultType { - @Override - public String typeInfo() { - return this.getClass().getAnnotation(CPSType.class).id(); + public String printNullable(PrintSettings cfg, Object f) { + if (f == null) { + return ""; } + return print(cfg, f); + } - @Override - public String toString() { - return typeInfo(); - } + protected abstract String print(PrintSettings cfg, @NonNull Object f); + + public String toString() { + return typeInfo(); } - @CPSType(id = "BOOLEAN", base = ResultType.class) + public abstract String typeInfo(); + + public abstract T getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException; + + protected abstract List getFromResultSetAsList(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException; + @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class BooleanT extends PrimitiveResultType { + public static class BooleanT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final BooleanT INSTANCE = new BooleanT(); @@ -93,6 +77,11 @@ public String print(PrintSettings cfg, Object f) { return (Boolean) f ? "1" : "0"; } + @Override + public String typeInfo() { + return "BOOLEAN"; + } + @Override public Boolean getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getBoolean(resultSet, columnIndex); @@ -105,9 +94,8 @@ protected List getFromResultSetAsList(ResultSet resultSet, int columnIn } - @CPSType(id = "INTEGER", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class IntegerT extends PrimitiveResultType { + public static class IntegerT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final IntegerT INSTANCE = new IntegerT(); @@ -119,6 +107,11 @@ public String print(PrintSettings cfg, Object f) { return f.toString(); } + @Override + public String typeInfo() { + return "INTEGER"; + } + @Override public Integer getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getInteger(resultSet, columnIndex); @@ -130,9 +123,8 @@ protected List getFromResultSetAsList(ResultSet resultSet, int columnIn } } - @CPSType(id = "NUMERIC", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class NumericT extends PrimitiveResultType { + public static class NumericT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final NumericT INSTANCE = new NumericT(); @@ -144,6 +136,11 @@ public String print(PrintSettings cfg, Object f) { return f.toString(); } + @Override + public String typeInfo() { + return "NUMERIC"; + } + @Override public Double getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getDouble(resultSet, columnIndex); @@ -155,9 +152,8 @@ protected List getFromResultSetAsList(ResultSet resultSet, int columnInd } } - @CPSType(id = "DATE", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class DateT extends PrimitiveResultType { + public static class DateT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final DateT INSTANCE = new DateT(); @@ -170,6 +166,15 @@ public String print(PrintSettings cfg, @NonNull Object f) { return print(number, cfg.getDateFormatter()); } + public static String print(Number num, DateTimeFormatter formatter) { + return formatter.format(LocalDate.ofEpochDay(num.intValue())); + } + + @Override + public String typeInfo() { + return "DATE"; + } + @Override public Number getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getDate(resultSet, columnIndex); @@ -179,49 +184,49 @@ public Number getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetPr protected List getFromResultSetAsList(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getDateList(resultSet, columnIndex); } - - public static String print(Number num, DateTimeFormatter formatter) { - return formatter.format(LocalDate.ofEpochDay(num.intValue())); - } } /** * A DateRange is provided by in a query result as two ints in a list, both standing for an epoch day (see {@link LocalDate#toEpochDay()}). * The first int describes the included lower bound of the range. The second int descibes the included upper bound. */ - @CPSType(id = "DATE_RANGE", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class DateRangeT extends PrimitiveResultType> { + public static class DateRangeT extends ResultType> { @Getter(onMethod_ = @JsonCreator) public static final DateRangeT INSTANCE = new DateRangeT(); @Override public String print(PrintSettings cfg, @NonNull Object f) { - if (!(f instanceof List)) { - throw new IllegalStateException(String.format("Expected a List got %s (Type: %s, as string: %s)", f, f.getClass().getName(), f)); - } - List list = (List) f; - if (list.size() != 2) { - throw new IllegalStateException("Expected a list with 2 elements, one min, one max. The list was: " + list); - } + Preconditions.checkArgument(f instanceof List, "Expected a List got %s (Type: %s, as string: %s)", f, f.getClass().getName(), f); + + final List list = (List) f; + + Preconditions.checkArgument(list.size() == 2, "Expected a list with 2 elements: one min, one max. The list was: %s", list); + final DateTimeFormatter dateFormat = cfg.getDateFormatter(); final Integer min = (Integer) list.get(0); final Integer max = (Integer) list.get(1); + if (min == null || max == null) { log.warn("Encountered incomplete range, treating it as an open range. Either min or max was null: {}", list); } // Compute minString first because we need it either way - String minString = min == null || min == CDateRange.NEGATIVE_INFINITY ? "-∞" : ResultType.DateT.print(min, dateFormat); + final String minString = min == null || min == CDateRange.NEGATIVE_INFINITY ? "-∞" : ResultType.DateT.print(min, dateFormat); if (cfg.isPrettyPrint() && min != null && min.equals(max)) { // If the min and max are the same we print it like a singe date, not a range (only in pretty printing) return minString; } - String maxString = max == null || max == CDateRange.POSITIVE_INFINITY ? "+∞" : ResultType.DateT.print(max, dateFormat); + final String maxString = max == null || max == CDateRange.POSITIVE_INFINITY ? "+∞" : ResultType.DateT.print(max, dateFormat); return minString + cfg.getDateRangeSeparator() + maxString; } + @Override + public String typeInfo() { + return "DATE_RANGE"; + } + @Override public List getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getDateRange(resultSet, columnIndex); @@ -233,9 +238,8 @@ public List> getFromResultSetAsList(ResultSet resultSet, int colum } } - @CPSType(id = "STRING", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class StringT extends PrimitiveResultType { + public static class StringT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final StringT INSTANCE = new StringT(); @@ -253,9 +257,14 @@ public StringT(BiFunction valueMapper) { @Override protected String print(PrintSettings cfg, @NonNull Object f) { if (valueMapper == null) { - return super.print(cfg, f); + return f.toString(); } - return super.print(cfg, valueMapper.apply(f, cfg)); + return valueMapper.apply(f, cfg); + } + + @Override + public String typeInfo() { + return "STRING"; } @Override @@ -269,9 +278,8 @@ protected List getFromResultSetAsList(ResultSet resultSet, int columnInd } } - @CPSType(id = "MONEY", base = ResultType.class) @NoArgsConstructor(access = AccessLevel.PRIVATE) - public static class MoneyT extends PrimitiveResultType { + public static class MoneyT extends ResultType { @Getter(onMethod_ = @JsonCreator) public static final MoneyT INSTANCE = new MoneyT(); @@ -284,24 +292,27 @@ public String print(PrintSettings cfg, Object f) { return IntegerT.INSTANCE.print(cfg, f); } - @Override - public BigDecimal getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { - return resultSetProcessor.getMoney(resultSet, columnIndex); - } - - @NotNull public BigDecimal readIntermediateValue(PrintSettings cfg, Number f) { return new BigDecimal(f.longValue()).movePointLeft(cfg.getCurrency().getDefaultFractionDigits()); } + @Override + public String typeInfo() { + return "MONEY"; + } + + @Override + public BigDecimal getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { + return resultSetProcessor.getMoney(resultSet, columnIndex); + } + @Override protected List getFromResultSetAsList(ResultSet resultSet, int columnIndex, ResultSetProcessor resultSetProcessor) throws SQLException { return resultSetProcessor.getMoneyList(resultSet, columnIndex); } } - @CPSType(id = "LIST", base = ResultType.class) @Getter @EqualsAndHashCode(callSuper = false) public static class ListT extends ResultType> { @@ -322,7 +333,7 @@ public String print(PrintSettings cfg, @NonNull Object f) { } // Not sure if this escaping is enough final LocaleConfig.ListFormat listFormat = cfg.getListFormat(); - StringJoiner joiner = listFormat.createListJoiner(); + final StringJoiner joiner = listFormat.createListJoiner(); for (Object obj : (List) f) { joiner.add(listFormat.escapeListElement(elementType.print(cfg, obj))); } @@ -331,7 +342,7 @@ public String print(PrintSettings cfg, @NonNull Object f) { @Override public String typeInfo() { - return this.getClass().getAnnotation(CPSType.class).id() + "[" + elementType.typeInfo() + "]"; + return "LIST[" + elementType.typeInfo() + "]"; } @Override @@ -343,10 +354,5 @@ public List getFromResultSet(ResultSet resultSet, int columnIndex, ResultSetP protected List> getFromResultSetAsList(final ResultSet resultSet, final int columnIndex, final ResultSetProcessor resultSetProcessor) { throw new UnsupportedOperationException("Nested lists not supported in SQL mode"); } - - @Override - public String toString() { - return typeInfo(); - } } }