private Object convertPropertyValue()

in core/src/main/java/com/jetbrains/youtrackdb/internal/core/sql/executor/ResultInternal.java [217:446]


  private Object convertPropertyValue(Object value) {
    if (value == null) {
      return null;
    }

    if (PropertyTypeInternal.isSingleValueType(value)) {
      return value;
    }

    switch (value) {
      case LinkBag linkBag -> {
        var list = new ArrayList<RID>(linkBag.size());
        for (var rid : linkBag) {
          list.add(rid);
        }

        return list;
      }
      case Blob blob -> {
        if (!blob.getIdentity().isPersistent()) {
          return blob.toStream();
        }
        return blob.getIdentity();
      }
      case Entity entity -> {
        if (entity.isEmbedded()) {
          return entity.detach();
        }
        final var rid = entity.getIdentity();
        return session.isTxActive() && !rid.isPersistent() ?
            session.refreshRid(rid) :
            rid;
      }

      case ContextualRecordId contextualRecordId -> {
        addMetadata(contextualRecordId.getContext());
        return new RecordId(contextualRecordId);
      }

      case Identifiable id -> {
        var res = id.getIdentity();
        if (session != null) {
          res = session.refreshRid(res);
        }

        return res;
      }
      case Result result -> {
        var resultSession = result.getBoundedToSession();
        if (resultSession != null && resultSession != session) {
          throw new DatabaseException(
              "Result is bound to different session, cannot use it as property value");
        }

        if (result.isEntity()) {
          return convertPropertyValue(result.asEntity());
        } else if (result.isBlob()) {
          return convertPropertyValue(result.asBlob());
        }
        if (result.isEdge()) {
          if (!result.isStatefulEdge()) {
            return result.asEdge();
          }

          return convertPropertyValue(result.asStatefulEdge());
        }
        if (result.isRelation()) {
          return result.asRelation();
        }

        return result;
      }
      case Object[] array -> {
        List<Object> listCopy = null;
        var allIdentifiable = false;

        for (var o : array) {
          var res = convertPropertyValue(o);

          if (res instanceof Identifiable) {
            allIdentifiable = true;
            if (listCopy == null) {
              //noinspection unchecked,rawtypes
              listCopy = (List<Object>) (List) new LinkListResultImpl(array.length);
            }
          } else {
            if (allIdentifiable) {
              var lst = new EmbeddedListResultImpl<>(array.length);
              lst.addAll(listCopy);

              listCopy = lst;
              allIdentifiable = false;
            }
            if (listCopy == null) {
              listCopy = new EmbeddedListResultImpl<>(array.length);
            }
          }

          listCopy.add(res);
        }
        if (listCopy == null) {
          listCopy = new EmbeddedListResultImpl<>();
        }
        return listCopy;
      }
      case List<?> collection -> {
        List<Object> listCopy = null;
        var allIdentifiable = false;

        for (var o : collection) {
          var res = convertPropertyValue(o);

          if (res instanceof Identifiable) {
            allIdentifiable = true;
            if (listCopy == null) {
              //noinspection unchecked,rawtypes
              listCopy = (List<Object>) (List) new LinkListResultImpl(collection.size());
            }
          } else {
            if (allIdentifiable) {
              var lst = new EmbeddedListResultImpl<>(collection.size());
              lst.addAll(listCopy);

              listCopy = lst;
              allIdentifiable = false;
            }
            if (listCopy == null) {
              listCopy = new EmbeddedListResultImpl<>(collection.size());
            }
          }

          listCopy.add(res);
        }

        if (listCopy == null) {
          listCopy = new EmbeddedListResultImpl<>();
        }
        return listCopy;
      }
      case ResultSet resultSet -> {
        var resultList = new ArrayList<>();
        resultSet.forEachRemaining(result -> resultList.add(convertPropertyValue(result)));
        return resultList;
      }
      case Set<?> set -> {
        Set<Object> setCopy = null;

        var allIdentifiable = false;

        for (var o : set) {
          var res = convertPropertyValue(o);
          if (res instanceof Identifiable) {
            if (setCopy == null) {
              //noinspection unchecked,rawtypes
              setCopy = (Set<Object>) (Set) new LinkSetResultImpl(set.size());
            }
            allIdentifiable = true;
          } else {
            if (allIdentifiable) {
              throw new IllegalArgumentException(
                  "Invalid property value, if set contains identifiables, it should contain only them");
            }
            if (setCopy == null) {
              setCopy = new EmbeddedSetResultImpl<>(set.size());
            }
          }

          setCopy.add(res);
        }

        if (setCopy == null) {
          setCopy = new EmbeddedSetResultImpl<>();
        }

        return setCopy;
      }

      case Map<?, ?> map -> {
        Map<String, Object> mapCopy = null;
        var allIdentifiable = false;

        for (var entry : map.entrySet()) {
          var key = entry.getKey();

          if (!(key instanceof String stringKey)) {
            throw new IllegalArgumentException(
                "Invalid property value, only maps with key types of String are supported : " +
                    key);
          }

          var res = convertPropertyValue(entry.getValue());
          if (res instanceof Identifiable) {
            allIdentifiable = true;
            if (mapCopy == null) {
              //noinspection unchecked,rawtypes
              mapCopy = (Map<String, Object>) (Map) new LinkMapResultImpl(map.size());
            }
          } else {
            if (allIdentifiable) {
              throw new IllegalArgumentException(
                  "Invalid property value, if map contains identifiables, it should contain only them");

            }
            if (mapCopy == null) {
              mapCopy = new EmbeddedMapResultImpl<>(map.size());
            }
          }

          mapCopy.put(stringKey, res);
        }

        if (mapCopy == null) {
          mapCopy = new EmbeddedMapResultImpl<>();
        }

        return mapCopy;
      }
      case Relation<?> biLink -> {
        if (biLink.isLightweight()) {
          return biLink;
        } else {
          return convertPropertyValue(biLink.asEntity());
        }
      }
      default -> {
        throw new CommandExecutionException(
            "Invalid property value for Result: " + value + " - " + value.getClass().getName());
      }
    }
  }