From 47494971026143197e6b55a749f9f730e9e488a0 Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Fri, 11 Nov 2022 14:42:12 +0100 Subject: [PATCH] WIP: SELECT for GRPC API --- .../server/datatype/DoubleDatatype.java | 2 + .../server/datatype/IntegerDatatype.java | 2 + .../caosdb/server/datatype/TextDatatype.java | 3 + .../server/grpc/CaosDBToGrpcConverters.java | 74 ++++++++++++++++--- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java b/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java index e9e25265..f3f17ace 100644 --- a/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/DoubleDatatype.java @@ -34,6 +34,8 @@ public class DoubleDatatype extends AbstractDatatype { try { if (value instanceof GenericValue) { return parse(((GenericValue) value).toDatabaseString()); + } else if (value instanceof CollectionValue) { + throw ServerMessages.DATA_TYPE_DOES_NOT_ACCEPT_COLLECTION_VALUES; } else { return parse(value.toString()); } diff --git a/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java b/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java index 0b1116ed..f3a58a4a 100644 --- a/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/IntegerDatatype.java @@ -33,6 +33,8 @@ public class IntegerDatatype extends AbstractDatatype { try { if (value instanceof GenericValue) { return new GenericValue(Long.parseLong(((GenericValue) value).toDatabaseString())); + } else if (value instanceof CollectionValue) { + throw ServerMessages.DATA_TYPE_DOES_NOT_ACCEPT_COLLECTION_VALUES; } else { return new GenericValue(Long.parseLong(value.toString())); } diff --git a/src/main/java/org/caosdb/server/datatype/TextDatatype.java b/src/main/java/org/caosdb/server/datatype/TextDatatype.java index af06ed6d..3b32fadc 100644 --- a/src/main/java/org/caosdb/server/datatype/TextDatatype.java +++ b/src/main/java/org/caosdb/server/datatype/TextDatatype.java @@ -23,6 +23,7 @@ package org.caosdb.server.datatype; import org.caosdb.server.entity.Message; +import org.caosdb.server.utils.ServerMessages; @DatatypeDefinition(name = "Text") public class TextDatatype extends AbstractDatatype { @@ -31,6 +32,8 @@ public class TextDatatype extends AbstractDatatype { public SingleValue parseValue(final Object value) throws Message { if (value instanceof GenericValue) { return (GenericValue) value; + } else if (value instanceof CollectionValue) { + throw ServerMessages.DATA_TYPE_DOES_NOT_ACCEPT_COLLECTION_VALUES; } return new GenericValue(value.toString()); } diff --git a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java index af40f735..f9ba7b3c 100644 --- a/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java +++ b/src/main/java/org/caosdb/server/grpc/CaosDBToGrpcConverters.java @@ -616,29 +616,31 @@ public class CaosDBToGrpcConverters { } return result; } - + private org.caosdb.api.entity.v1.Value.Builder getSelectedValue(Selection s, EntityInterface e) { org.caosdb.api.entity.v1.Value.Builder result = org.caosdb.api.entity.v1.Value.newBuilder(); String selector = s.getSelector(); switch (selector) { case "value": - if(e.hasValue()) { - result = convert(e.getValue()); + if (e.hasValue()) { + return convert(e.getValue()); } break; case "name": if (e.hasName()) { result.setScalarValue(convertStringValue(e.getName())); + return result; } break; case "id": result.setScalarValue(convertStringValue(e.getId().toString())); - break; + return result; case "description": if (e.hasDescription()) { result.setScalarValue(convertStringValue(e.getDescription())); + return result; } break; @@ -646,18 +648,21 @@ public class CaosDBToGrpcConverters { if (e.hasUnit()) { final String unit = getStringUnit(e); result.setScalarValue(convertStringValue(unit)); + return result; } break; case "datatype": if (e.hasDatatype()) { result.setScalarValue(convertStringValue(e.getDatatype().toString())); + return result; } break; - case "path": if (e.hasFileProperties() && e.getFileProperties().hasPath()) { result.setScalarValue(convertStringValue(e.getFileProperties().getPath())); + return result; } + break; case "parent": if (e.hasParents()) { CollectionValues.Builder parents = CollectionValues.newBuilder(); @@ -665,12 +670,13 @@ public class CaosDBToGrpcConverters { parents.addValues(ScalarValue.newBuilder().setStringValue(p.getName())); } result.setListValues(parents); + return result; } - + break; default: // selector for a normal property + List<org.caosdb.api.entity.v1.Value.Builder> results = new LinkedList<>(); for (Property p : e.getProperties()) { - // TODO(tf) - handle multiple matching properties if (p.getName() != null && p.getName().equals(selector)) { if (s.getSubselection() == null) { // no subselection -> just return the actual value @@ -680,41 +686,53 @@ public class CaosDBToGrpcConverters { throw new TransactionException(m); } - result = convert(p.getValue()); + results.add(convert(p.getValue())); } else { // with subselection, e.g. p1.unit, site.geolocation.longitude switch (s.getSubselection().getSelector()) { case "name": if (p.hasName()) { + result = org.caosdb.api.entity.v1.Value.newBuilder(); result.setScalarValue(convertStringValue(p.getName())); + results.add(result); } break; case "id": + result = org.caosdb.api.entity.v1.Value.newBuilder(); result.setScalarValue(convertStringValue(p.getId().toString())); + results.add(result); break; case "description": if (p.hasDescription()) { + result = org.caosdb.api.entity.v1.Value.newBuilder(); result.setScalarValue(convertStringValue(p.getDescription())); + results.add(result); } break; case "unit": final String unit = getStringUnit(p); if (unit != null) { + result = org.caosdb.api.entity.v1.Value.newBuilder(); result.setScalarValue(convertStringValue(unit)); + results.add(result); } break; case "datatype": if (p.hasDatatype()) { + result = org.caosdb.api.entity.v1.Value.newBuilder(); result.setScalarValue(convertStringValue(p.getDatatype().toString())); + results.add(result); } break; case "value": - if(p.hasValue()) { + if (p.hasValue()) { + result = org.caosdb.api.entity.v1.Value.newBuilder(); result = convert(p.getValue()); + results.add(result); } break; default: @@ -723,16 +741,48 @@ public class CaosDBToGrpcConverters { if (v instanceof ReferenceValue) { EntityInterface referenced_entity = ((ReferenceValue) v).getEntity(); - return getSelectedValue(s.getSubselection(), referenced_entity); + result = getSelectedValue(s.getSubselection(), referenced_entity); + results.add(result); } else if (v instanceof CollectionValue) { - // TODO(tf) + for (Value i : (CollectionValue) v) { + if (i instanceof ReferenceValue) { + EntityInterface referenced_entity = ((ReferenceValue) i).getEntity(); + result = getSelectedValue(s.getSubselection(), referenced_entity); + results.add(result); + } else { + // Non-reference scalar value + result = getSelectedValue(s.getSubselection(), p); + results.add(result); + } + } + } else { + // Actual sub-property + result = getSelectedValue(s.getSubselection(), p); + results.add(result); } break; } } } } - break; + if (results.size() > 1) { + // There have been multiple matching properties + CollectionValues.Builder values = CollectionValues.newBuilder(); + for (org.caosdb.api.entity.v1.Value.Builder v : results) { + // Concatenate all found values to a list + if (v.hasScalarValue()) { + values.addValues(v.getScalarValueBuilder()); + } else { + values.addAllValues(v.getListValuesBuilder().getValuesList()); + } + } + result = org.caosdb.api.entity.v1.Value.newBuilder(); + result.setListValues(values); + } else if (results.size() == 1) { + // There has been exactly one matching property + result = results.get(0); + } + return result; } return result; } -- GitLab